針對Ajax請求

一、HTTP請求相關

1、http請求包含以下七個步驟:

   1.建立TCP連接

   2.web瀏覽器向服務器發送請求命令

   3.web瀏覽器發送請求頭信息

   4.web服務器應答

   5.web服務器發送應答頭信息

   6.web服務器向瀏覽器發送數據

   7.web服務器關閉TCP連接

2.http請求一般由四部分組成(區分應答)

   1.請求的方法,一般是GET或POST請求

   2.請求的URL,就是請求的地址

   3.請求頭,包含一些客戶端環境信息,身份驗證信息

   4.請求體,包含客戶提交的查詢字符串信息,表單信息等。


3.GET和POST請求的區別:

   GET:一般用於獲取信息

            GET請求會將請求的信息以字符串的形式加載頁面的URL中,所以該方法是不安全的。

             有數量的限制,在2000個字符串

   POST:一般用於修改服務器上的資源,比如增刪改,當然也具備get請求的功能。

             沒有數量限制。

4.一個HTTP響應一般由三部分組成

   1.一個數字和文字組成的狀態碼,用來顯示請求成功或失敗。狀態碼參考文末圖片

   2.響應頭,響應頭和請求頭一樣也包含許多有用的信息,比如服務器類型,日期時間,內容類型和長度等。

   3.響應體,即響應正文


二、XMLHttpRequest對象

 1.創建該對象使用new關鍵字來創建一個XMLHTTPRequest對象。

2.方法:

   1. open(method,url,async)方法:

     使用該方法後不會立即發送請求,而是定義了請求的發送方式,地址,是否異步

     參數:method=》請求方式,比如GET或POST

               url=》 請求地址

               async=》 請求是否異步執行,默認爲true,false爲同步

   2. send(string)方法:

   使用send方法後就會想服務器發送請求,參數是請求的主體,不一定是一個字符串,也可以是一個FormData對象。

  3. setRequestHeader(參數)方法,對於GET請求無效

   該方法定義了請求信息以什麼樣的編碼方式傳遞,有三個方式

  1. 1. application/x-www-form-urlencoded(默認)  
  2. 2.text/plain  
  3. 3.multipart/form-data 
  4. setRequestHeader('content-type':'application/x-www-form-urlencoded')這種格式

4.abort()方法,用於取消當前響應,關閉連接並結束任何未決的網絡活動。

     就是說該方法會將XML的readyState變爲0的狀態。

5.getAllResponseHeaders(),把HTTP未解析的響應頭作爲字符串返回。

   當readyState小於3時,會返回null。否則,會返回所有的服務器發送的響應頭

6.getResponseHeader(),返回指定的HTTP響應頭的值。

    其參數是要返回的 HTTP 響應頭部的名稱

3.屬性

 1.readyState,HTTP 請求的狀態.當一個 XMLHttpRequest 初次創建時,這個屬性的值從 0 開始,直到接收到完整的 HTTP 響應,這個值增加到 4。

 各個參數代表的含義: 

    0.XML對象被創建成功

    1.open方法調用,但send方法未調用,請求還沒發送

    2.send方法也以調用,請求發送出去了

    3.web瀏覽器接收到響應頭信息,開始接收響應體但未完成

    4.完全接收到響應體


2.responseText,代表瀏覽器接收到的響應體,但不包含頭信息。

  當readyState爲4時,該屬性就包含了響應體的全部信息。

  響應體一般是一個JSON對象,一般用JSON.parse(XML.responseText)方法轉化爲js對象

  那通常要確認瀏覽器已經收到了響應體,一般是做兩層判斷,

var XML = new XMLHttpRequest();
if(XML.readyState === 4){
   if(XML.status === 200){
        .....
    }
   }
就是狀態碼也返回200,纔去執行相關操作

3.status,就是狀態碼


4.事件

onReadyStatechange,當readyState屬性值改變的時候會調用該事件。

三、jQuery中的AJAX

  jQuery已經封裝好了對AJAX請求的方法,像下面這樣

$.ajax({
  type:'POST',
  url:'',
  data:{},
  dataType:'',
  success:function(data){},
  error:function(XML){}
})

解釋一下,type和url很清楚了
data:是一個對象,連同請求一起發送到服務器的數據,get請求一般可以不指定。
dataType:期望收到的數據的格式,一般是JSON,不過不寫的話JQ會只能的去判斷
success:請求成功後執行的回調函數,參數是返回的數據,以及包含服務器的響應值等等
error:請求失敗執行的回調函數,傳入XML對象

四、跨域

   一個地址由http(協議)//www(子域名).baidu(主域名):80(端口號)/server.php(請求資源地址)

   來組成。

那隻要前臺請求是與當前的地址的協議,子域名,主域名,端口號任意一個不相同,都算作跨域。

JavaScript出於安全方面的考慮,不允許調用其他頁面的對象,就是說不能跨域請求資源。

如何解決跨域問題呢?

一般由以下方法:

1.

比如www.beijing.com要請求上海服務器www.shanghai.com的資源,
可以通過代理,由後臺操作,北京服務器先向上海服務器請求完資源,然後前臺訪問北京服務器加載該資源

2.JSONP

  該方法只支持GET請求實現跨服,因爲該方式會將請求的數據放在url中。

  具體實現的原理:

  在HTML標籤中,有src屬性的標籤通常都擁有跨域的能力,比如image,script,ifram。

  簡單來說就是,在js中規定一個回調函數,用來接收數據,然後創建一個script標籤,src屬性爲接口地址。

  最後將script標籤返回來的內容是一個執行函數,函數名爲上述的回調函數名,將要請求的數據當做參數傳入。

  具體代碼想這樣:

var getData(data){
   console.log(data)
}

var script = document.createElement('script');
var url = '跨域的地址';
script.setAttribute('src',url);'
document.body.appendChild(src);

3.window.name + iframe跨域獲取數據

   基本原理:比如在一個index.html的頁面下,新建一個<iframe>標籤。每一個iframe標籤都有屬於自己的window.name屬性(也就是該iframe的contentWindow的name值),並且該值不會隨着iframe的重定向而改變,這樣就可以將數據放到上面,然後再取了。

具體代碼:

 <script type="text/javascript"> 
    function crossDomain(url, fn) {
      iframe = document.createElement('iframe');
      iframe.style.display = 'none';
      var state = 0;
    
      iframe.onload = function() {
        if(state === 1) {
          fn(iframe.contentWindow.name);
          iframe.contentWindow.document.write('');
          iframe.contentWindow.close();
          document.body.removeChild(iframe);
        } else if(state === 0) {
          state = 1;
          iframe.contentWindow.location = 'http://localhost:81/cross-domain/proxy.html';
        }
      };
        //解釋一下,當第一次指定iframe.src的地址爲跨域的服務器地址的時候,iframe.contentWindow.name服務器已經傳遞數據給到了該值,這時候調用任務隊列的onload函數,這時state ===0;然後將iframe重定向至一個同源地址,改變state===1。而此前服務器傳過來的數據,也就是ifra.contentWindow.name是不會變的,再次加載onload的時候,就可以去操作iframe取得數據
      iframe.src = url;
      document.body.appendChild(iframe);
    } 
    
    // 調用
    // 服務器地址
    var url = 'http://localhost:8080/data.php';
    crossDomain(url, function(data) { // 處理數據 data就是window.name的值(string)
      var data = JSON.parse(iframe.contentWindow.name);
      console.log(data);
    });
  </script>

4.location.hash + iframe 跨域請求獲取數據

   原理:這個跟window.name + iframe 是差不多的。只不過該方法是將服務器傳過來的數據放在了iframe.contentWindow.location.hash屬性上。

 代碼實例:

<script type="text/javascript">
    function getData(url, fn) {
      var iframe = document.createElement('iframe');
      iframe.style.display = 'none';
      iframe.src = url;

      iframe.onload = function() {
        fn(iframe.contentWindow.location.hash.substring(1));
        window.location.hash = '';
        document.body.removeChild(iframe);
      };

      document.body.appendChild(iframe);
    }

    // get data from server
    var url = 'http://localhost:8080/data.php';
    getData(url, function(data) {
      var jsondata = JSON.parse(data);
      console.log(jsondata.name + ' ' + jsondata.age);
    });
  </script>

5.postMessage方法

   基本原理:也是利用iframe display:none的方式,向其他域傳送數據。

   語法:postMessage('data',url);第一個參數是要傳的數據,一般以字符串形式。第二個是跨域的地址。

   代碼實例:

比如在a.com頁面向b.com頁面傳送數據
那麼要在a頁面創建一個iframe,src指向b.html
<iframe id="iframe" display:none src=http://b.com>
在script中:
獲取到iframe節點
var iframe = document.getElementById('iframe');
iframe.postMessage('我是來自a頁面的數據','http://b.com');
這樣就把數據發送給b頁面了。但是在b頁面中還要定義一個函數來接收該數據,
因此,在b.html中使用onMessage事件來監聽數據的接收
window.addEventListener('message',function(event){
   //爲了安全起見要判斷一下消息的來源
   console.log(event.source)      //bwindow 就是b頁面的window對象,或者是a頁面iframe的contenWindow
   console.log(event.origin)      //http://a.com
   console.log(event.data)        //接收的數據
})

6.WebSocket 

  使用WebSocket方式,不僅可以由客戶端發起請求,還可以從服務器端發起。且不受同源策略的限制。

 使用起來也簡單,舉個例子

var ws = new WebSocket("wss://echo.websocket.org");  //新建一個WebSocket對象,傳入跨域請求的地址

ws.onopen = function(evt) { 
  console.log("Connection open ..."); 
  ws.send("Hello WebSockets!");
};

ws.onmessage = function(evt) {
  console.log( "Received Message: " + evt.data);
  ws.close();
};

ws.onclose = function(evt) {
  console.log("Connection closed.");
};      

一些簡單的WebSocket對象的屬性和方法

 *readyState返回WebSocket對象的當前狀態,有四種情況:

     0 表示正在連接;1 表示連接成功; 2 表示正在關閉連接; 3 表示連接已經關閉

 *onopen 用於指定連接成功後的回調函數,一般在該回調裏面發送數據。

 *onclose  用於指定連接關閉後的回調函數

  *onmessage  用於指定接收到服務器數據後的回調函數,一般會在該回調裏關閉連接

  *onerror  用於報錯時的回調函數

  *send()方法,用於發送數據

   *close()方法,用於關閉連接

  7.CORS  

   


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章