使用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」請求頭爲這個值