XMLHttpRequest
使用 XMLHttpRequest 對象可以和服務器進行交互,可以獲取到數據,而無需讓整個頁面進行刷新.這樣 web 頁面可以做到只更新局部頁面,降低了對用戶操作的影響.
XMLHttpRequest 對象可以用於獲取各種類型的數據,而不止是 xml,還支持 JSON,HTML 或者純文本
本地服務器
let http = require("http");
let url = require("url");
const port = 3333;
http.createServer((request, response) => {
response.setHeader("Access-Control-Allow-Origin", "*");
response.writeHead(200, { "Content-type": "text/html;charset=utf8" });
if (request.url !== "/favicon.ico") {
let pathname = url.parse(request.url).pathname;
pathname = pathname.replace(/\//, "");
if (pathname === "get_money") {
get_money(request, response);
}
response.end("\r\n錢給完了,沒了", "utf-8");
}
}).listen(port);
console.log(`本地服務器創建成功=>localhost:${port}`);
function get_money(request, response) {
response.write("給了你666塊錢", "utf-8");
}
安裝個 node,跑在本地就行
status/readyState/onreadystatechange
- onreadystatechange
- 當 readyState 值變化時,會調用相應的處理函數
- readyState
- 0=>UNSENT=>XMLHttpRequest 代理被創建,但尚未調用 open() 方法
- 1=>OPENED=>open() 方法已經被調用,可以通過 setRequestHeader() 方法來設置請求的頭部, 可以調用 send() 方法來發起請求
- 2=>HEADERS_RECEIVED=>send() 方法已經被調用,響應頭也已經被接收
- 3=>LOADING=>響應體部分正在被接收。如果 responseType 屬性是 text 或空字符串, responseText 將會在載入的過程中擁有部分響應數據
- 4=>DONE=>請求操作已經完成。這意味着數據傳輸已經徹底完成或失敗
- status
- 在請求完成前,status 的值為 0.XMLHttpRequest 出錯,瀏覽器返回的 status 也為 0
- 如果服務器響應中沒有明確指定 status 碼,XMLHttpRequest.status 將會默認為 200
var xhr = new XMLHttpRequest();
console.log("open調用前的status", xhr.status); // open調用前的status 0
console.log("open調用前的readyState", xhr.readyState); //open調用前的readyState 0
xhr.open("GET", "http://127.0.0.1:3333/get_money", true);
console.log("open調用后的status", xhr.status); //open調用后的status 0
console.log("open調用后的readyState", xhr.readyState); //open調用后的readyState 1
xhr.send();
console.log("send調用后的status", xhr.status); //send調用后的status 0
console.log("send調用后的readyState", xhr.readyState); //send調用后的readyState 1
xhr.onreadystatechange = function() {
console.log(xhr.status); //2,3,4
console.log(xhr.readyState); //200,200,200
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
}
};
readyState 代表 send()方法已經被調用,但是 send()之后 readyState 不一定就是 2
當服務器指定了 status,其實就是 http 的狀態碼
//node中writeHead修改一下
response.writeHead(404, { "Content-type": "text/html;charset=utf8" });
response/responseText/responseType
- response
- 返回響應的正文
- 返回的類型可以是 ArrayBuffer,Blob,Document,Object,DOMString.這取決於 responseType 屬性
- 請求尚未完成或未成功,則取值是 null
- 讀取文本數據時如果將 responseType 的值設置成 text 或空字符串且當請求狀態還在是 readyState (3) 時,response 包含到目前為止該請求已經取得的內容
- responseText
- 返回一個 DOMString,包含對文本請求的響應,請求不成功或者請求尚未發送,返回 null
- 在請求完成之前將會得到部分屬性
- 如果值不是 text 或者 string,responseType 將會拋出 InvalidStateError 異常
- responseType
- responseType 屬性是一個枚舉類型的屬性,返回響應數據的類型
- 設置為一個空字符串,它將使用默認的 text 類型
- 同步請求設置 responseType 會拋出一個 InvalidAccessError 的異常
- "","arraybuffer","blob","document","json","text"
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://127.0.0.1:3333/get_money", true);
xhr.onreadystatechange = function() {
console.log("readyState=>", xhr.readyState);
console.log("status=>", xhr.status);
console.log(xhr.response);
console.log(xhr.responseText);
};
xhr.send();
open 和 send
- open(method,url,async,user,password)
- XMLHttpRequest 的 http 或者 https 的請求必須通過 open 來發起
- 必須要在 send 之前調用
- method('GET','POST','PUT','DELETE').url 請求地址.async 是否開啟同步請求,默認 true,執行異步操作.用戶名用於認證,默認 null.密碼用於認證,默認 null
- 同步的請求會阻塞 js 執行,不需要調用 onreadystatechange 事件監聽器
- sendRequestHeader(header,value)
- 在 open() 方法和 send() 之間調用
- 多次對同一個請求頭賦值,只會生成一個合並了多個值的請求頭
- send()
- 用於發送 http 請求,異步請求會在請求發送后立即返回,如果是同步請求,會在響應到達后才返回
- send()接收一個可選參數,作為請求主體.如果請求方法是 GET 或 HEAD,則將請求主體設為 null
- 發送二進制內容的最佳方法是結合 ArrayBufferView 或者Blobs
- 參數['null','ArrayBuffer','ArrayBufferView','Blob','Document','FormData','DOMString']
一個小案例
通過請求發送一個留言,通過 FormData 發送一個表單數據
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://127.0.0.1:3333/add", true);
var body = new FormData();
body.append("oid", 8029794);
body.append("type", 1);
body.append("message", "本大王來巡山了");
body.append("plat", 1);
body.append("jsonp", "jsonp");
body.append("csrf", "af15b2a3a0e64a2ea304f885bea6bfd1");
xhr.send(body);
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log(xhr.response);
}
};
為了安全,跨域 XHR 對象有一些限制:
- 不能使用 setRequestHeader() 設置自定義頭部
- 不能發送和接收 cookie
- 調用 getAllResponseHeaders() 方法總會返回空字符串
屬性
- responseURL
- responseXML
- statusText
- timeout
- upload
- withCredentials
方法
- abort()
- getAllReponseHeaders()
- getResponseHeader()
- overrideMimeType()
事件
- loadstart
- progress
- abort
- error
- load
- timeout
- loadend
- readystatechange