function success(text) { console.log('Success:' + text); } function fail(code) { console.error('Error Code: ' + code); } // 新建XMLHttpRequest對象 var request = new XMLHttpRequest(); // 狀態發生改變時,執行回調函數 request.onreadystatechange = function() { // 判斷請求是否完成 if(request.readyState === 4) { // 判斷響應結果 if(request.status === 200) { // 請求成功,返回響應數據 return success(request.responseText); } else { // 請求失敗,返回狀態碼 return fail(request.status) } } else { // Http請求還在繼續中... } } // 發送Http請求 request.open('GET', '/api/test'); request.send(); alert('請求已發送,請等待響應...')
要點:html
- 常看瀏覽器是否支持XMLHttpRequest:
window. XMLHttpRequest;
- 建立XMLHttpRequest對象:
var request = new XMLHttpRequest();
XMLHttpRequest對象的經常使用屬性:ajax
- onreadystatechange(請求狀態是否改變)
- readyState(請求狀態碼,4表示請求已完成)
- status(響應狀態碼,200表示正確響應)
- responseText(具體響應內容)
XMLHttpRequest對象的經常使用方法:json
open()(該方法有三個參數)api
- 參數1:指定請求方法(GET / POST / HEAD)
- 參數2:指定URL(注意:該URL是相對路徑)
- 參數3:指定是否異步(true / false),默認爲true
send()(真正發送請求,該方法有一個參數)數組
- 若建立的POST請求,須要傳遞參數body
- 若建立的GET請求,能夠省略該參數,或傳null
// 只須要把XMLHTTPRequest()改成ActiveXObject('Microsoft.XMLHTTP')便可; var request = new ActiveXObject('Microsoft.XMLHTTP');
由於ActiveXObject對象的屬性和方法和XMLHTTPRequest對象是同樣的:promise
// 所以能夠整合標準寫法和低版本IE上的寫法 var request; if(window.XMLHTTPRequest) { request = new XMLHTTPRequest(); } else { request = new ActiveXObject('Microsoft.XMLHTTP') }
var xhr= $.ajax('/api/test',{ dataType: 'json' }); // 不須要open() send(), 請求在建立完後即執行 // jQuery建立的xhr對象相似於一個Promise對象 xhr.done((data) => { console.log('Success: ' + JSON.stringify(data)); }).fail((xhr, status) => { console.error('Error: ' + xhr.status + ', Reason: ' + status); }).always(() => { console.log('請求完成: 不管成功或失敗都會調用'); });
要點:瀏覽器
$.ajax()方法包含兩個參數app
- 參數1:請求URL;
- 參數2:一個可選的setting對象;
setting配置異步
- async:是否爲異步請求,缺省爲true;
- method:http請求方法,缺省爲'GET',還可設爲'POST','PUT';
- headers:額外的http請求頭,需爲object對象;
- data:發送的數據,能夠爲字符串、數組或對象;
- contentType:發送POST請求的格式,缺省爲'application/x-www-form-urlencoded',也可設爲'text/plain'、'application/json'等;
- dataType:接受數據的格式,能夠爲'html'、'json'、'text'等,缺省值根據contentType自動斷定;
jQuery ajax語法糖:async
$.get():發送一個get請求,第二個參數能夠爲一個object,jq會自動拼接爲string
$.get('api/test',{ name: 'huang xin', age: 18 }) // 等價於 /api/test?name=huang%xin&age=18$.post():發送一個post請求,第二個參數缺省被序列化application/x-www-form-urlencoded
$.post('api/test',{ name: 'huang xin', age: 18 }) // 以 name=huang%xin&age=18 做爲body發送post請求- $.getJSON():發送一個get請求,並返回一個JSON對象;
// ajax將返回promise對象 function ajax(method, url, data) { let request = new XMLHttpRequest(); return new Promise((resolve,reject) => { request.onreadystatechange = () => { if(request.readyState === 4) { if(request.status === 200) { resolve(request.responseText); } else { reject(request.status); } } } request.open(method,url); request.send(data); }); } var p = ajax('GET','/api/test'); p.then((text) => { // ajax成功,得到響應內容; console.log('Success: ' + text); }).catch((code) => { // ajax失敗,得到狀態碼; console.error('Error Code: ' + code); })
練習:使用XHR模擬$.ajax的實現
var options = { url: 'test.me', // 請求地址 type: 'GET', // 請求方式 data: {name:'hx', age:18}, // 請求參數 dataType: 'json', // 數據返回格式 success: function(text,xml) { // 請求成功回調 // 請求成功後的業務邏輯 }, fail: function(status) { // 請求失敗回調 // 請求失敗後的業務邏輯 } } function ajax(options) { // 各step的代碼 } // ajax(options); 實際調用
function createXHR() { var xhr; if(window.XMLHTTPRequest) { xhr = new XMLHTTPRequest(); } else { xhr = new ActiveXObject('Microsoft.XMLHTTP') } return xhr; }()
if(options.type == 'GET') { xhr.open('GET',buildGetUrl(options.url,options.data)); xhr.send(); } else if(options.type == 'POST') { xhr.open('POST',options.url); xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded') xhr.send(options.data) } else { // 其餘請求方法,如: // xhr.open('HEAD',options.url); // ... }
xhr.onreadystatechange = function() { if(xhr.readyState === 4) { if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) { options.success(xhr.responseText,xhr.responseXML); } else { options.fail(xhr.status) } } }
buildGetUrl(url,params) { for(let item in params) { url += (url.includes('?') ? '&':'?'); url += encodeURIComponent(item) + '=' + encodeURIComponent(params[item]); } return url; }