ajax

ajax
1.什麼是ajax
         asynchronous javascript and xml,是一種異步加載數據的方式,可使用 ajax實現頁面的局部刷新。
2.如何使用ajax
     ajax的核心對象是 XMLHttpRequest
     1.get:向服務器取得數據,根據服務器的實現不一樣, getpost也能夠實現相同的功能,固然也都能向服務器傳送取得數據,和 rxe標準是有衝突的,不建議這樣使用。
         get數據放到了 URL中,由於放在了 URL中, get發送的數據是有限制的,2048個字節,會產生一個安全性的隱患。
     2.post:向服務器發送數據, POST請求放到了請求體中,會用 https對包進行加密,安全性比較好

 

         1.建立AJAX
              var xhr = new XMLHttpRequest(); 
         4.監聽請求
            xhr.onreadystatechange = function(){
            //當xhr的readystate屬性發生了改變,則觸發事件。
            //readystate狀態,
            //0表示=》xhr對象已經建立,可是沒有初始化,至關於new了一個對象,可是沒有open();
            //1表示,xhr已經調用open(),
            //2表示,xhr已經發出了ajax請求,調用了send()的時候。
            //3表示,數據已經返回了部分
            //4表示,數據已經所有返回
                if(xhr.readyState !== 4){
                    return;
                }
                if(xhr.status >= 200 && xhr.status <= 300){
                    //數據存放在了xhr.responseText的屬性中(String)
                    document.querySelector("h1").innerHTML = xhr.responseText;
                }else{
                    console.error("請求出錯");
                }
            }
         2.打開這個對象
              xhr.open("get","../js/test.txt",true);//true表明異步方式,false就是同步的方式發送 
         3.發送請求
              xhr.send(); 

post方法javascript

    1.建立一個xhr的對象(post)
      var xhr = new XMLHttpRequest(); 
     5.監聽數據是否返回。
        xhr.onreadystatechange = function(){
            if(xhr.readyState !== 4){
                return;
            }
            if(xhr.status >= 200 && xhr.status <= 300){
                //咱們須要一個JOSN的對象,
                var resp = JSON.parse(xhr.responseText);
                if(resp.result){
                    console.log("ok");
                }else{
                    console.log("error");
                }
            }else{
                console.error("請求出錯");
            }
        }
    2.配置這個對象。post的數據放入了body中,就如同傳入一個參數被send當作一個body的內容發送。
          xhr.open("post","../js/test.php",true); 
    3.爲了讓服務器理解表單格式,設立表單頭和方法
          xhr.setRequestHeader("content","application/x-www-form-urlencoded"); 
    4.發送表單數據
          xhr.send("user=gap&password=123456"); 
3.JSON 
     1.Javascript Object Natation,是一種輕量級的數據交換格式。是由 ECMA定義的, functionundefined是不能做爲值傳遞的。
         數據格式:   
         Object:{"name":"john","age":18}; //對象形式
                      arr:["john",18]; //數組形式
                     value: string,number,object,array,true false,null
     2.JS的對象子集,於JS進行無縫對接。
     3.JSON數據與JS對象的轉換。
         JSON:JSJSON.parse(data); 
         JS:JSONJSON.stringify(JSObj); 

 

1.回調地獄,promise
     1.回調地獄
        x= getDate();
        y = getMoreDate();
        z = getMoreDate();
        //若是當x還在數據傳輸中,沒有完成數據返回,就被y調用,就會出現錯誤。
        //若是使用一層一層的回調,會致使回調層級特別深,開發維護成本高,因此在es6中提出了promise對象。
        getDate(function(x){
            getMoreDate(x,function(y){
                getMoreDate(y,function(z){
                    process z;
                })
            })
        })

 

     2.promise
        1.能夠經過 promise構造函數建立一個對象,能夠解決回調地獄,它不只支持一個回調,還支持回調與回調之間的連續調用。
        2.這個 promise實際上有三種狀態, pending等待, fulfill知足了條件的返回狀態, reject延時對象,沒有知足
        3. promise的構造函數有一個參數,是一個回調,他接受兩個參數,這兩個參數都能改變 promise的狀態,第一個參數能夠從 pending切換到 fulfill,第二個參數能夠將 pending切換到 reject狀態。
            var prom = new Promise(function(resolve,reject){
                setTimeout(function(){
                    var num = Math.floor(Math.random() * 100);
                    if(num % 2 === 0){
                        resolve(num);
                    }else{
                        reject(num);
                    }
                },3000)
                
            });
            //使用promise的一個回調,成功的時候會調用then函數,失敗的時候調用catch函數。
            prom.then(function(num){
                console.log("resolve:" + num);
            }).catch(function(num){
                console.log("reject:" + num);
            });

 

     3.Ajax的依賴調用。
        1例子,有一篇文章,第一次取得第一段文章,第二次取得第二段文章,第三次取得第三段文章,第四次取得第四段文章。
        意味着取得有順序,第一次返回以前,不能運行第二次。這和回調地獄有點類似,能夠用promise來解決這種鏈式調用,鏈式調用過深難以維護。這裏用jquery來演示
            var article = "";
            $.get("../para/p1.txt",function(p1){
                article += p1 + "<br />";
                $.get("../para/p2.txt",function(p2){
                    article += p2 + "<br />";
                    $.get("../para/p3.txt",function(p3){
                        article += p3 + "<br />";
                        $.get("../para/p4.txt",function(p4){
                            article += p4 + "<br />";
                            $("h1").html(article);
                        })
                    })
                })
            })

 

    4.Promise解決Ajax的依賴調用
        function getDate1(){
            return new Promise(function(resolve,reject){
                $.get("../para/p1.txt",function(p1){
                    resolve(p1);
                })
            })
        }    
        function getDate2(){
            return new Promise(function(resolve,reject){
                $.get("../para/p2.txt",function(p2){
                    resolve(p2);
                })
            })
        }    
        function getDate3(){
            return new Promise(function(resolve,reject){
                $.get("../para/p3.txt",function(p3){
                    resolve(p3);
                })
            })
        }    
        function getDate4(){
            return new Promise(function(resolve,reject){
                $.get("../para/p4.txt",function(p4){
                    resolve(p4);
                })
            })
        }        
        var article = "";
        //getDate返回了一個promise對象,因此能夠調用then方法
        getDate1().then(function(p1){
            article += p1 + "<br />";
            return getDate2();
        }).then(function(p2){
            article += p2 + "<br />";
            return getDate3();
        }).then(function(p3){
            article += p3 + "<br />";
            return getDate4();
        }).then(function(p4){
            article += p4 + "<br />";
            $("h1").html(article);
        });

 

     promise的all()
         promise若是原生的使用是比較難用的,這裏 promise.all()就是 promise的精華,有了這個,才能真正的實現 promise的用途,好比給個數組
        promise.all([
            p1,
            p2,
            p3
        ]).then();
        要等待 promise裏面的數組全都完成了以後,它會統一的來返回一個 then,好比
            promise.all([
                $.ajax({url:'data/1.json',dataType:'json'}),
                $.ajax({url:'data/2.json',dataType:'json'}),
                $.ajax({url:'data/3.json',dataType:'json'}),
            ]).then((arr)=>{//由於有三個結果,因此返回的是一個數組,第一個function表明resovle,第二個function表明reject,這裏也可使用箭頭函數,若是想要獲取arr裏面的數據,也能夠直接將[data1,data2,data3]寫到形參裏。
                let [data1,data2,data3] = arr;
            },(res)=>{
                console.log('error');
            })

 

            這裏就是用 jqueryajax的方法用異步的方式來進行模擬同步的方式,這裏不存在順序的問題,由於數據只有都完成了,而後把數據按照順序一次所有返回,若是一個接口有問題,全失敗。all的執行時間等於最慢的那個 ajax,三個是並行在走的, promise.all()最大的缺點就是沒有任何邏輯在裏面,好比若是咱們須要先執行a,b依賴於a的結果,這裏就須要用到 asyncawait了。
     async/await
         async/await已經取代了 genrator, async/await是專門用來配合 promise的,它模擬同步的方式來寫異步的東西,這裏不是一個普通的函數,這裏是一個 ansyc函數,這裏麪包含的是異步操做,以下,
        aysnc funtion show(){//也能夠寫成箭頭函數 let show = async() =>{}
            let data1 = await $.ajax({url:'data/1.json',dataType:'json'});//準確的說await後面跟的是一個promise對象,可是jquery的ajax自己是包含promise的
            let data2 = await $.ajax({url:'data/2.json',dataType:'json'});
            let data3 = await $.ajax({url:'data/3.json',dataType:'json'});
            console.log(data1,data2,data3);
        }
        show();

 

        這裏幾乎是用同步的寫法來寫一個異步的操做了,注意點
            1.儘管咱們是在用一種同步的方式在寫,但它背後依然是以異步的方式來執行, async只是爲了你寫的方便,它須要通過背後一套編譯的東西,
            2.這個 async/await是這樣的格式,
                 aysnc function(){}固然也能夠是  let xxx = async()=>{}
            它能夠像正常函數同樣寫代碼,可是若是裏面有了 promise操做,就須要加上一個 await,等到這個函數結束了之後,代碼就會往下執行,簡單來講 async這個函數是能夠暫停的,這一點繼承了生成器函數 generator, async/await只是方便了模擬同步閱讀操做的效率,而不會變成真正的同步的操做,它背後的性能依舊是回調的那些方式,很是的高,
        加入邏輯操做,若是第一個失敗了,第二個成功了的操做方式,示例
        let show = async() =>{
            let data1 = await $.ajax({url:'data/1.json',dataType:'json'});
            if(data1.a<10){
                let data2 = await $.ajax({url:'data/2.json',dataType:'json'});
                console.log('a<10');
            }else{
                let data3 = await $.ajax({url:'data/3.json',dataType:'json'});
                console.log('a>10');
            }
        }
        show();

 

         1.json裏面是一個對象 {'a':12};
        若是某些成功某些失敗也可使用 try/catch
        promise幾乎不能獨立存在,它單獨使用很是的難用,讓promise大放異彩的就是async/await,它有一個專門的說法叫語法糖,它是讓你用相似同步的方式寫代碼,可是當瀏覽器真正執行這個代碼的時候,它會把這些函數編譯回原來的那種嵌套回調寫法,
2.Ajax同源策略 
     1.什麼事同源策略,
        瀏覽器的一種安全機制,源指,協議,域名,端口號,當咱們腳本在運行時,瀏覽器會檢測,它運行的腳本和取得數據與咱們的 html頁面所在的源是否相同,至關於協議,域名,端口號是否和瀏覽器html的協議,域名,端口號是否一致。若是相同則是同源請求,若是不一樣就是跨域請求。默認狀況下,瀏覽器不支持跨域請求。
     2.解決跨域問題
         1.JSONP
            //這個方法不受同源策略的限制。也能夠用js生成方法名,比較靈活
                function getData(da1){
                    console.log(da1);
                }
                var script = document.createElement("script");
                script.id = "JSONP";
                script.src = "../js/JSONP.js";
                document.body.appendChild(script);

 JSONP.js的代碼php

getData({"name":"john","age":18});
//012ajax.html使用的

 

         運用百度取詞練習
            function getData(data){
                var script = document.querySelector("#JSONP");//選擇剛建立的jsonp
                script.parentNode.removeChild(script);//由於input的keyup事件,因此每次輸入都清除掉上一次的結果
                $("ul").html("");//同時也清楚掉ul裏面的結果。
                for(var i = 0;i < data.g.length;i++){//由於返回的是對象,遍歷對象
                    for(var index in data.g[i]){//用for in 方法遍歷對象
                        var p1 = data.g[i][index]; //將對象的值寫入p1
                        var p2 = index;}
                        $("<li>"+ p1 + "--" + p2 +"</li>").appendTo("ul");
                    }
            }
            function getList(wd){
                var script = document.createElement("script");//建立一個script
                script.id = "JSONP";//id
                script.src = "https://www.baidu.com/sugrec?&prod=pc&cb=getData&wd=" + wd;
                document.body.appendChild(script);//將jsonp文件放入樹中;
            }
            $("input").keyup(function(){
                var wd = $(this).val();
                getList(wd);
            });

 

         2.CORS
            跨域資源共享是通常瀏覽器都支持的功能(ie10以上),由瀏覽器自動完成, corsajax和普通的 ajax實現是同樣的, cors關鍵在服務器端支持了跨域通訊就行,普通 ajax直接發出 cors請求,在頭信息中包含 origin的字段, origin源是由瀏覽器自動追加的,指本次請求來自哪一個源,服務器就根據這個值是否贊成執行尋求,瀏覽器加了 origin源以後,若是服務器發現 origin再也不它的許可範圍內,就返回一個正常的 http的響應,瀏覽器就發現這個迴應的頭裏面沒有包含跨域請求容許的信息,就知道出錯,而後拋出一個異常,不然,瀏覽器容許跨域,返回對應的狀態以及狀態碼200,
            $.get("http://localhost/cors/cors.php",function(data){
                console.log(data);
            })

 cors.php代碼html

<?php
    $person = array('name'=>'josh','age'=>18);
    header("Access-Control-Allow-Origin:*"); //在頭信息上寫入一個origin,要否則瀏覽器不能接受到跨域請求,則報錯,能夠寫上指定的域名,或者寫上*
    echo json_encode($person);

?>
相關文章
相關標籤/搜索