最近看了下《Javascript高級程序設計》(第三版)關於Ajax部分,做了這篇筆記。
一、常規用法
第一步,創建XHR對象
var xhr = new XMLHttpRequest();
此方法兼容IE7+, 針對IE6需要使用new ActiveXObject("Microsoft.XMLHTTP");
第二步,准備請求
xhr.open("get","/testajax",false);
參數分別為: 請求類型 、url、是否異步
第三步,發送請求
get請求的話就是xhr.send(null)
send需要一個參數,因為get請求中參數會在url中,所以這里寫null(之所以寫null是因為不寫的話在某些瀏覽器會有問題)。
如果是post請求,那么這里面就寫post請求需要的參數。
但是首先需要設置content-type,例如:
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
然后發送數據xhr.send("fname=Bill&lname=Gates");
第四步,請求發出去后,服務器響應的內容會自動填充到xhr對象的屬性上
有這些屬性
responseText 返回的文本
responseXML 如果content-type為"text/xml'或者"application/xml"就把數據放這個屬性
status HTTP狀態碼
statusText 狀態說明
第五步、根據status檢查請求狀態
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText )
}else{}
無論類型是什么,響應主題內容都會保存在responseText屬性中。
對於非xml格式數據而言,responseXML為null。
第六步,如果是異步請求,那么需要監聽readyState來判斷請求的狀態
通過onreadystatuschange事件判斷readyState的值
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
console.log("success")
}
};
其他注意點:
setRequestHeader用來設置頭信息
getResponseHeader得到響應頭信息
getAllResponseHeaders得到全部響應頭信息
get請求中,對參數使用encodeURIComponent方法
post請求中,設置content-type,參數序列化傳入,格式和get請求一樣
如果不設置content-type,那么后台就必須從raw request header中去得到參數
二、xhr2中的功能
1: FormData()序列化表單數據
var data = new FormData();
data.append("hello","world");
xhr.send(data);
或者
xhr.send(document.forms[0])
這樣可以快速傳入post參數,而且無需設置content-type。
2: timeout超時
xhr.timeout = 1000; //設置超時時間
xhr.ontimeout = function(){}; //處理超時情況
xhr.send(null);
3:overrideMimeType
重寫MIME,MIME決定了你的responseXML或者responseText的值是否存在
MIME由content-type設置
4:進度事件,用來監視xhr的進度。
提供了一系列的事件,可以做類似網頁加載進度條的效果。
三、跨域
CORS實現ajax的跨域訪問
1: 標准的實現:
首先,先發送一個跨域ajax請求(這里可以檢測是否支持CORS,通過新建一個xhr對象,檢測xhr2中的屬性是否存在在這個對象來實現)。
然后,普通情況下,我們肯定會發現控制台報錯,類似無法訪問跨域資源這種錯誤。
這時需要服務器設置
Access-Control-Allow-Origin:* 代表所有域名都可以訪問到
Access-Control-Allow-Origin: http://www.cnblogs.com 限定了域名
請求和響應均不包含cookie信息
2: IE的實現:
通過XDomainRequest()來實現。
直接改變contenttype屬性來實現post請求
xdr.contentType= "";
不能發送同步請求
3: 自定義頭部:
在CORS中是不支持的,但是有固定接口可以設置的頭部來傳輸信息。
4: 帶憑證的請求(cookie、ssl等):
客服端通過withCredentials設置為true來實現
服務器返回相應的頭部來確認即可。
四、其他跨域技術
1: 動態創建一個圖片,src跨域,然后可以返回一個像素圖或者204;
返回后的處理在onload和onerror里面
可以用於一些數據統計方面。
2: JSONP
五、服務器推送
1、輪詢
2、長輪詢
3、HTTP流
4、SSE
5、Web Sockets
先發一個http請求過去,服務器相應后會把http協議變為web socket協議
鏈接變為 ws://
var socket = new WebSocket("ws://xxx.com")
沒有同源限制
通過 socket.readyState 來判斷鏈接狀態
socket.close()關閉
數據交互
socket.send("xxx");發送消息
消息內容只能是純文本,所以對於復雜的數據需要序列化
socket.onmessage = function(event){
var data = event.data; //這里是服務器返回的數據
}