權威指南之腳本化http

使用javascript代碼操做http是可行的。當用腳本設置window對象的location屬性或調用表單對象的submit方法時,都會初始化http請求。這兩種狀況下,瀏覽器會加載新頁面。javascript

ajax描述了一種使用腳本操縱http的web應用框架。ajax應用的主要特色是使用腳本操縱http和web服務器進行數據交換,不會致使頁面重載。在某種意義上,comet與ajax相反。在comet中,web服務器發起通訊並異步發送消息到客戶端。若是web應用要相應服務器發送的消息,則它會使用ajax技術發送或請求數據。php

實現ajax和comet的方式有不少種,而這些底層的實現有時稱爲傳輸協議。例如 img元素有一個src屬性。當腳本設置這個屬爲url時,瀏覽器發起的httpget請求會從這個url下載圖片。所以,腳本經過設置img元素的src屬性,且把信息做爲圖片url的查詢字符串部分,就把能通過編碼信息傳遞給web服務器。img元素沒法實現完整的ajax傳輸協議。由於數據交換生單向的css

爲了把iframe做爲ajax傳輸協議使用,腳本首先要把發送給web服務器的信息編碼到url中,而後設置iframe的src屬性爲該url。服務器能建立一個包含響應內容的html文檔,並把它返回給web瀏覽器,而且在iframe中顯示它。iframe須要對用戶不可見,例如可使用css隱藏它,腳本能經過遍歷ifame的文檔對象來讀取服務器的響應。這種房屋受限於同源策略html

實際上 script元素的src屬性能設置url併發起htttpget請求,使用script元素實現腳本操做http是很是吸引人的。由於他們能夠跨域通訊而不受限於同源策略。使用基於script的ajax傳輸協議時,服務器的響應採用json編碼的數據格式,當執行腳本時,javascript解析器能自動將其解碼。因爲他使用json數據格式,所以這種ajax傳輸協議也叫作jsonpjava

全部瀏覽器都支持XMLHttpRequest對象,它定義了API,除了經常使用的GET請求,這個API還包括實現POST請求的能力,同時它能用文本或Document對象的形式返回服務器的響應。web

瀏覽器在XMLHttpRequest類上定義了它們的http API.這個類的每一個實例都表示一個獨立的請求/響應對,而且這個對象的屬性和方法容許指定請求細節和提取相應數據ajax

使用這個HTTP API必須作的第一件事就是實例化XMLHttpRequest對象json

var request=new XMLHttpRequest();跨域

也能重用已存在的XMLHttpRequest,但注意這將終止以前經過該對象掛起的任何請求。ie7以前的版本不支持非標準的XMLHttpRequest()構造函數,但能模擬瀏覽器

if(window.XMLHttpRequest===undefined){
  window.XMLHttpRequest=function(){
    try{
      return new ActiveXOject("Msxml2.XMLHTTP.6.0");
    }
    catch(e1){
      
      try{
        return new ActiveXObject("Msxml2.XMLHTTP.3.0");
      }
      catch(e2)
      {
        throw new Error("XMLHttpRequest is not supported");
        
      } 

    }
    
  };

}

 一個http請求有4部分組成

一、http請求方法或動做

二、正在請求的URL

三、一個可選的請求頭集合,可能包含身份驗證信息

4一個可選的請求主體

服務器返回的http響應包含3部分

一、一個數字和文字組成的狀態碼,用來顯示請求的成功和失敗

二、一個響應頭集合

三、響應主體

建立XMLHttpRequest對象以後,發起HTTP請求的下一步是調用XMLHttpRequest對象的open方法去指定這個請求的兩個必需部分:方法和URL

request.open("GET","data.csv");

若是有請求頭的話,請求進程的下個步驟是設置它,例如,post請求須要「Content-Type」頭指定請求主體的MIME類型:

request.setRequestHeader("Content-Type","text/plain");

使用XMLHttpRequest發起HTTP請求的最後一步是指定可選的請求主體並向服務器發送它。使用send方法像以下這樣作

request.send(null);

get請求絕對沒有主體,因此應該傳遞null或省略這個參數。post請求一般擁有主體,同時它應該匹配使用setRequestHeader指定的「Content-Type」頭;

http請求的各部分有指定順序:請求方法和URL首先到達。而後是請求頭,最後是請求主體。

function postMessage(msg){
  var request=new XMLHttpRequest();
  request.open("post","/log.php");
  request.setRequestHeader("Content-Type","text/plain;charset=UTF-8");
  request.send(msg);
}

一個完整的HTTP響應有狀態碼、響應頭集合和響應主體組成。這些均可以經過XMLHttpRequest對象的屬性和方法使用:

status和statusText屬性以數字和文本的形式返回HTTP狀態碼(200 請求成功 404找不到資源  500)

使用getResponseHeader和getAllResponseHeaders()能查詢響應頭

響應主體能夠從responseText屬性中獲得文本形式的,從responseXML屬性中獲得Document形式的、

XMLHttpRequest對象一般異步使用:發送請求後,send方法當即返回,知道響應返回,前面列出的響應方法和屬性纔有效。爲了在響應準備就緒時獲得通知,必需監聽XMLHttp對象上的readystatechange事件

readyState是一個整數,它指定了HTTP請求的狀態

當readyState值改變爲4或服務區的響應完成時,全部的瀏覽器都觸發readystatechange事件。由於在響應完成以前也會觸發事件,因此事件處理程序應該一直檢驗readyState值。爲了監聽readystatechange事件,請把事件處理函數設置爲XMLHttpRequest對象的onreadystatechange屬性。也能使用addEventListener(或在IE8以及以前版本中使用attachEvent),但一般每一個請求只須要一個處理程序,因此只設置onreadystatechange更容易

function getText(url,callback){
  var request=new XMLHttpRequest();
  request.open("GET",url);
  request.onreadystatechange=function(){
    if(request.readyState===4&&request.status===200){
      var type=request.getResponseHeader("Content-Type");
      if(type.mathc(/^text/)){
        
        callback(request.responseText);
      }
      
    }

  };
  request.send(null);
}

XMLHttpRequest支持同步響應。若是把false做爲第三個參數傳遞給open,那麼send方法將阻塞直到請求完成,這這種狀況下,不須要使用事件處理程序:一旦send返回,僅須要檢查XMLHttpRequest對象的status和responseText屬性

function getTextSync(url){
  var request=new XMLHttpRequest();
  request.open("get",url,false);
  request.send(null);
  if(requset.status!==200){
    throw new Error(request.statusText);
  }
  var type=request.getResponseHeader("Content-Type");
  if(!type.mathc(/^text/)){
    throw new Error("expecte textual response;got:"+type);
    
  }
  return request.responseText;
}
function get(url,callback){
  var request=new XMLHttpRequest();
  request.open("get",url);
  request.onreadystatechange=function(){
    if(request.readyState===4&&request.status==200){
     var type=request.getResponseHeader("Content-Type");  
    if(type.indexOf("xml")!==-1&&request.responseXML){
      callback(request.responseXML);
    }
      else if(type==="application/json"){
        callback(JSON.parse(request.responseText));
      }
      else
        callback(request.responseText);
  }
  
       };  
  request.send(null);
}

你可能但願特殊編碼的另外一個響應類型是「application/javascript」或者"text/javascript".你能使用XMLHttpRequest請求javaScript腳本,而後使用全局eval();

request.overrideMimeType("text/plain;charset=utf-8");

表單編碼的請求

默認狀況下,html表單經過post方法發送給服務器,而編碼後的表單數據則用作請求主體。對錶單數據使用的編碼方案相對簡單:對每一個表單元素的名字和值執行普通的URL編碼(使用十六進制轉義碼替換特殊字符),使用等號把編碼後的名字和值分開,並使用&符號分開名/值

find=pizza$zipcode=02134&radius=1km

表單數據編碼格式有一個正式的MIME類型

application/x-www-form-urlencoded

當使用post方法提交這個順序的表單數據時,必需設置「content-type」請求頭爲這個值

相關文章
相關標籤/搜索