前端之AJAX

北京-IT拾荒者發表於2018-07-03

JSON

是一種輕量級的資料交換格式。JSON是用字串來表示Javascript物件;

json字串就是js物件的一種表現形式(字串的形式)

var person = {"name":"alex",
             "sex":"men",
             "teacher":{
                "name":"tiechui",
                 "sex":"half_men",
             },
             "bobby":['basketball','running'],

              "getName":function() {return 80;}
             };
alert(person.name);
alert(person.getName());
alert(person.teacher.name);
alert(person.bobby[0]);
複製程式碼

parse()和.stringify()

parse() 用於從一個json字串中解析出json物件,如
var str = '{"name":"yuan","age":"23"}'
結果:JSON.parse(str)     ------>  Object  {age: "23",name: "yuan"}

stringify()用於從一個json物件解析成json字串,如
var c= {a:1,b:2} 
結果:  JSON.stringify(c)     ------>      '{"a":1,"b":2}'

注意1:單引號寫在{}外,每個屬性名都必須用雙引號,否則會丟擲異常。
注意2:
a={name:"yuan"};   //ok
b={'name':'yuan'}; //ok
c={"name":"yuan"}; //ok
alert(a.name);  //ok
alert(a[name]); //undefined
alert(a['name']) //ok
複製程式碼

什麼是AJAX

AJAX(Asynchronous Javascript And XML)翻譯成中文就是“非同步Javascript和XML”。即使用Javascript語言與伺服器進行非同步互動,傳輸的資料為XML(當然,傳輸的資料不只是XML,現在用的較多的是json)。

同步互動:客戶端發出一個請求後,需要等待伺服器響應結束後,才能發出第二個請求;

非同步互動:客戶端發出一個請求後,無需等待伺服器響應結束,就可以發出第二個請求。

AJAX除了非同步的特點外,還有一個就是:瀏覽器頁面區域性重新整理;(這一特點給使用者的感受是在不知不覺中完成請求和響應過程)

AJAX常見應用情景

前端之AJAX
當我們在百度中輸入一個“老”字後,會馬上出現一個下拉選單!列表中顯示的是包含“傳”字的4個關鍵字。

其實這裡就使用了AJAX技術!當檔案框發生了輸入變化時,瀏覽器會使用AJAX技術向伺服器傳送一個請求,查詢包含“傳”字的前10個關鍵字,然後伺服器會把查詢到的結果響應給瀏覽器,最後瀏覽器把這4個關鍵字顯示在下拉選單中。

整個過程中頁面沒有重新整理,只是重新整理頁面中的區域性位置而已!

當請求發出後,瀏覽器還可以進行其他操作,無需等待伺服器的響應!

前端之AJAX
當輸入使用者名稱後,把游標移動到其他表單項上時,瀏覽器會使用AJAX技術向伺服器發出請求,伺服器會查詢名為zhangSan的使用者是否存在,最終伺服器返回true表示名為lemontree7777777的使用者已經存在了,瀏覽器在得到結果後顯示“使用者名稱已被註冊!”。

整個過程中頁面沒有重新整理,只是區域性重新整理了;

在請求發出後,瀏覽器不用等待伺服器響應結果就可以進行其他操作;

AJAX的優缺點 優點: AJAX使用Javascript技術向伺服器傳送非同步請求;

AJAX無須重新整理整個頁面;

因為伺服器響應內容不再是整個頁面,而是頁面中的區域性,所以AJAX效能高;

缺點: AJAX並不適合所有場景,很多時候還是要使用同步互動;

AJAX雖然提高了使用者體驗,但無形中向伺服器傳送的請求次數增多了,導致伺服器壓力增大;

因為AJAX是在瀏覽器中使用Javascript技術完成的,所以還需要處理瀏覽器相容性問題;

AJAX技術 四步操作: 建立核心物件;

使用核心物件開啟與伺服器的連線;

傳送請求

註冊監聽,監聽伺服器響應。

XMLHTTPRequest open(請求方式, URL, 是否非同步)

send(請求體)

onreadystatechange,指定監聽函式,它會在xmlHttp物件的狀態發生變化時被呼叫

readyState,當前xmlHttp物件的狀態,其中4狀態表示伺服器響應結束

status:伺服器響應的狀態碼,只有伺服器響應結束時才有這個東東,200表示響應成功;

responseText:獲取伺服器的響應體

AJAX核心(XMLHttpRequest) 其實AJAX就是在Javascript中多新增了一個物件:XMLHttpRequest物件。所有的非同步互動都是使用XMLHttpServlet物件完成的。也就是說,我們只需要學習一個Javascript的新物件即可。

var xmlHttp = new XMLHttpRequest();(大多數瀏覽器都支援DOM2規範)

注意,各個瀏覽器對XMLHttpRequest的支援也是不同的!為了處理瀏覽器相容問題,給出下面方法來建立XMLHttpRequest物件:

function createXMLHttpRequest() {
       var xmlHttp;
       // 適用於大多數瀏覽器,以及IE7和IE更高版本
       try{
           xmlHttp = new XMLHttpRequest();
       } catch (e) {
           // 適用於IE6
           try {
               xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
           } catch (e) {
               // 適用於IE5.5,以及IE更早版本
               try{
                   xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
               } catch (e){}
           }
       }            
       return xmlHttp;
   }

複製程式碼

開啟與伺服器的連線(open方法) 當得到XMLHttpRequest物件後,就可以呼叫該物件的open()方法開啟與伺服器的連線了。open()方法的引數如下:

open(method, url, async):

method:請求方式,通常為GET或POST;

url:請求的伺服器地址,例如:/ajaxdemo1/AServlet,若為GET請求,還可以在URL後追加引數;

async:這個引數可以不給,預設值為true,表示非同步請求;

var xmlHttp = createXMLHttpRequest();
xmlHttp.open("GET", "/ajax_get/", true);
複製程式碼

傳送請求 當使用open開啟連線後,就可以呼叫XMLHttpRequest物件的send()方法傳送請求了。send()方法的引數為POST請求引數,即對應HTTP協議的請求體內容,若是GET請求,需要在URL後連線引數。

注意:若沒有引數,需要給出null為引數!若不給出null為引數,可能會導致FireFox瀏覽器不能正常傳送請求!

xmlHttp.send(null);

接收伺服器響應

當請求傳送出去後,伺服器端Servlet就開始執行了,但伺服器端的響應還沒有接收到。接下來我們來接收伺服器的響應。

XMLHttpRequest物件有一個onreadystatechange事件,它會在XMLHttpRequest物件的狀態發生變化時被呼叫。下面介紹一下XMLHttpRequest物件的5種狀態:

0:初始化未完成狀態,只是建立了XMLHttpRequest物件,還未呼叫open()方法;

1:請求已開始,open()方法已呼叫,但還沒呼叫send()方法;

2:請求傳送完成狀態,send()方法已呼叫;

3:開始讀取伺服器響應;

4:讀取伺服器響應結束。

onreadystatechange事件會在狀態為1、2、3、4時引發。

下面程式碼會被執行四次!對應XMLHttpRequest的四種狀態!

xmlHttp.onreadystatechange = function() {
           alert('hello');
       };

複製程式碼

但通常我們只關心最後一種狀態,即讀取伺服器響應結束時,客戶端才會做出改變。我們可以通過XMLHttpRequest物件的readyState屬性來得到XMLHttpRequest物件的狀態。

xmlHttp.onreadystatechange = function() {
           if(xmlHttp.readyState == 4) {
               alert('hello');    
           }
       };
複製程式碼

其實我們還要關心伺服器響應的狀態碼是否為200,其伺服器響應為404,或500,那麼就表示請求失敗了。我們可以通過XMLHttpRequest物件的status屬性得到伺服器的狀態碼。

最後,我們還需要獲取到伺服器響應的內容,可以通過XMLHttpRequest物件的responseText得到伺服器響應內容。

xmlHttp.onreadystatechange = function() {
           if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
               alert(xmlHttp.responseText);    
           }
       };
複製程式碼

if 傳送POST請求: 需要設定請求頭:xmlHttp.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”);

請求完整程式碼:

<h1>AJAX</h1>
<button onclick="send()">測試</button>
<div id="div1"></div>
<script>
      function createXMLHttpRequest() {
           try {
               return new XMLHttpRequest();//大多數瀏覽器
           } catch (e) {
               try {
                   return new ActiveXObject("Msxml2.XMLHTTP");
               } catch (e) {
                   return new ActiveXObject("Microsoft.XMLHTTP");
               }
           }
       }

       function send() {
           var xmlHttp = createXMLHttpRequest();
           xmlHttp.onreadystatechange = function() {
               if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                   var div = document.getElementById("div1");
                   div.innerText = xmlHttp.responseText;
                   div.textContent = xmlHttp.responseText;
               }
           };
           xmlHttp.open("POST", "/ajax_post/", true);
           post: xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
           xmlHttp.send("b=B");  
       }
</script>
複製程式碼

AJAX例項(使用者名稱是否已被註冊)

<script type="text/javascript">
       function createXMLHttpRequest() {
           try {
               return new XMLHttpRequest();
           } catch (e) {
               try {
                   return new ActiveXObject("Msxml2.XMLHTTP");
               } catch (e) {
                   return new ActiveXObject("Microsoft.XMLHTTP");
               }
           }
       }

       function send() {
           var xmlHttp = createXMLHttpRequest();
           xmlHttp.onreadystatechange = function() {
               if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                   if(xmlHttp.responseText == "true") {
                       document.getElementById("error").innerText = "使用者名稱已被註冊!";
                       document.getElementById("error").textContent = "使用者名稱已被註冊!";
                   } else {
                       document.getElementById("error").innerText = "";
                       document.getElementById("error").textContent = "";
                   }
               }
           };
           xmlHttp.open("POST", "/ajax_check/", true, "json");
           xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
           var username = document.getElementById("username").value;
           xmlHttp.send("username=" + username);
       }
</script>
//--------------------------------------------------
<h1>註冊</h1>
<form action="" method="post">
使用者名稱:<input id="username" type="text" name="username" onblur="send()"/><span id="error"></span><br/>
密&emsp;碼:<input type="text" name="password"/><br/>
<input type="submit" value="註冊"/>
</form>
複製程式碼

jquery實現的ajax 快捷API:

<1>$.get(url, [data], [callback], [type])  //[]裡的表示可以不填
<2>$.post(url, [data], [callback], [type])  //type: text|html|json|script
複製程式碼

應用:

//請求引數應該儘量放在data引數中,因為可以自動編碼,手動拼接url要注意編碼問題
   function testWithDataAndCallback() {
       //$.post...
       $.get('/user/list', {type: 1}, function (data, callbacktype, jqXHR) {
           console.log(data);//將json字串解析成json物件
       });
   }
複製程式碼

-------------- <4>$.getJSON()

與$.get()是一樣的,只不過就是做後一個引數type必須是json資料了。
  一般同域操作用$.get()就可以,
  $.getJson 最主要是用來進行jsonp跨域操作的。
複製程式碼

核心API的基本使用:

<1>  $.ajax的兩種寫法:
         $.ajax("url",{})
         $.ajax({})

<2>  $.ajax的基本使用
   $.ajax({
       url:"//",
       data:{a:1,b:2},
       type:"GET",
       success:function(){}
   })

<3> 回撥函式
   
       $.ajax('/user/allusers', {
           success: function (data) {
               console.log(arguments);
           },
           error: function (jqXHR, textStatus, err) {
               // jqXHR: jQuery增強的xhr
               // textStatus: 請求完成狀態
               // err: 底層通過throw丟擲的異常物件,值與錯誤型別有關
               console.log(arguments);
           },
           complete: function (jqXHR, textStatus) {//成功失敗都執行
               // jqXHR: jQuery增強的xhr
               // textStatus: 請求完成狀態 success | error
               console.log('statusCode: %d, statusText: %s', jqXHR.status, jqXHR.statusText);
               console.log('textStatus: %s', textStatus);
           },
           statusCode: {
               '403': function (jqXHR, textStatus, err) {
                   console.log(arguments);  //注意:後端模擬errror方式:HttpResponse.status_code=500
                   
               },
               '400': function () {
               }
           }
       });
複製程式碼

核心API的重要欄位(引數):

<1> ----------請求資料相關: data, processData, contentType, traditional--------------
data: 當前ajax請求要攜帶的資料,是一個json的object物件,ajax方法就會預設地把它編碼成某種格式
(urlencoded:?a=1&b=2)傳送給服務端;此外,ajax預設以get方式傳送請求。
 # function testData() {
#   $.ajax("/test",{     //此時的data是一個json形式的物件
#      data:{
#        a:1,
#        b:2
#      }      
#   });                   //?a=1&b=2
processData:宣告當前的data資料是否進行轉碼或預處理,預設為true,即預處理;
iffalse,那麼對data:{a:1,b:2}會呼叫json物件的toString()方法,
即{a:1,b:2}.toString()最後得到一個[object,Object]形式的結果。   
{"1":"111","2":"222","3":"333"}.toString();//[object Object]
該屬性的意義在於,當data是一個dom結構或者xml資料時,我們希望資料不要進行處理,直接發過去,
就可以講其設為true。

contentType:預設值: "application/x-www-form-urlencoded"。傳送資訊至伺服器時
內容編碼型別。
用來指明當前請求的資料編碼格式;urlencoded:?a=1&b=2;如果想以其他方式提交資料,
比如contentType:"application/json",即向伺服器傳送一個json字串: 
   $.ajax("/ajax_get",{
      data:JSON.stringify({
          a:22,
          b:33
       }),
       contentType:"application/json",
       type:"POST",
   });                          //{a: 22, b: 33}
            # 注意:contentType:"application/json"一旦設定,data必須是json字串,不能是json物件
traditional:一般是我們的data資料有陣列時會用到 :data:{a:22,b:33,c:["x","y"]}, 
             traditional為false會對資料進行深層次迭代;          


<2> ------------------------ 響應資料: dataType、dataFilter------------------------

dataType:預期伺服器返回的資料型別,伺服器端返回的資料會根據這個值解析後,傳遞給回撥函式。
           # 預設不需要顯性指定這個屬性,ajax會根據伺服器返回的content Type來進行轉換;比如我們的伺服器響應的
           # content Type為json格式,這時ajax方法就會對響應的內容進行一個json格式的轉換,if轉換成功,我們在
           # success的回撥函式裡就會得到一個json格式的物件;轉換失敗就會觸發error這個回撥函式。如果我們明確地指
           # 定目標型別,就可以使用data Type。
           # dataType的可用值:html|xml|json|text|script
           # 見下dataType例項

dataFilter: 型別:Function 給 Ajax返回的原始資料的進行預處理的函式。見下dataFilter例項

<3> 請求型別 type:

   型別:String 預設值: "GET")。請求方式 ("POST""GET"), 預設為 "GET"。注意:其它 HTTP 請求方法,
   如 PUT 和 DELETE 也可以使用,但僅部分瀏覽器支援。

<4> 前置處理 beforeSend(XHR)

   型別:Function 傳送請求前可修改 XMLHttpRequest 物件的函式,如新增自定義 HTTP 頭。XMLHttpRequest 
   # 物件是唯一的引數。這是一個 Ajax 事件。如果返回 false 可以取消本次 ajax 請求。
   # 見下beforeSend例項
<5> jsonp  型別:String

   # 在一個 jsonp 請求中重寫回撥函式的名字。這個值用來替代在 "callback=?" 這種 GET 或 POST 請求中 URL 
   # 引數裡的 "callback" 部分,比如 {jsonp:'onJsonPLoad'} 會導致將 "onJsonPLoad=?" 傳給伺服器。

<6> jsonpCallback  型別:String

   # 為 jsonp 請求指定一個回撥函式名。這個值將用來取代 jQuery 自動生成的隨機函式名。這主要用來讓 jQuery 生
   # 成度獨特的函式名,這樣管理請求更容易,也能方便地提供回撥函式和錯誤處理。你也可以在想讓瀏覽器快取 GET 請求
   # 的時候,指定這個回撥函式名。
複製程式碼

前端之AJAX

識別圖中二維碼,領取python全套視訊資料

相關文章