jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype以後又一個優秀的JavaScript代碼庫(_或JavaScript框架_)。jQuery設計的宗旨是「write Less,Do More」,即倡導寫更少的代碼,作更多的事情。它封裝JavaScript經常使用的功能代碼,提供一種簡便的JavaScript設計模式,優化HTML文檔操做、事件處理、動畫設計和Ajax交互。做者我也是在2015年就開始用jQuery,那時候跟同事比看誰寫的代碼更短
如若看個jQuery源碼的同窗,j應該知道jq是對原生XHR的封裝,另外還增長了jsonp的支持,讓ajax請求能夠支持跨域請求,
可是要注意的是:jsonp請求本質不是XHR異步請求,就是請求了一個js文件,所以在瀏覽器的network面板中的xhr標籤下看不到jsonp的跨域請求,可是在js標籤下能看見,由於它利用src特性請求任何一個網站的資源。php
$.ajax({ url: "https://www.api.com/api/xxx", //ajax請求地址 cache: true,// 默認true,dataType 爲 script 和 jsonp 時默認爲 false。設置爲 false 將不緩存此頁面 type: "GET",//請求方式 "POST" 或 "GET", 默認爲 "GET"。注意:其它 HTTP 請求方法,如 PUT 和 DELETE 也可使用,但僅部分瀏覽器支持。 dataType: "json", //根據返回數據類型能夠有這些類型可選:xml html script json jsonp text timeout:Number //設置請求超時時間(毫秒), 此設置將覆蓋全局設置。 //發送到服務器的數據,能夠直接傳對象{a:0,b:1},若是是get請求會自動拼接到url後面,如:&a=0&b=1 //若是爲數組,jQuery 將自動爲不一樣值對應同一個名稱。如 {foo:["bar1", "bar2"]} 轉換爲 "&foo=bar1&foo=bar2"。 data: {}, //默認true設置下,全部請求均爲異步請求。若是須要發送同步請求,請將此選項設置爲 false。注意,同步請求將鎖住瀏覽器,用戶其它操做必須等待請求完成才能夠執行。 async: true, //發送請求前可修改 XMLHttpRequest 對象的函數。 //XMLHttpRequest 對象是惟一的參數。這是一個 Ajax 事件。 //若是返回false能夠取消本次ajax請求,也能設置一些http協議的header頭信息。 beforeSend:function(xhr){ // 也能夠禁用按鈕防止重複提交 $("#submit").attr({ disabled: "disabled" }); }, //context這個對象用於設置ajax相關回調函數的上下文。也就是說,讓回調函數內this指向這個對象(若是不設定這個參數,那麼this就指向調用本次AJAX請求時傳遞的options參數)。 //好比指定一個DOM元素做爲context參數,這樣就設置了success回調函數的上下文爲這個DOM元素。 context: document.body, //請求成功後的回調函數 success: function(data,textStatus){ //this 調用本次AJAX請求時傳遞的options參數 ,若是設置context來改變了this,那這裏的this就是改變過的 }, //請求失敗時調用此函數。有如下三個參數:XMLHttpRequest 對象、錯誤信息、(可選)捕獲的異常對象。 //若是發生了錯誤,錯誤信息(第二個參數)除了獲得null以外,還多是"timeout", "error", "notmodified" 和 "parsererror"。 error:function(XMLHttpRequest, textStatus, errorThrown){ // 一般 textStatus 和 errorThrown 之中 // 只有一個會包含信息 // this 調用本次AJAX請求時傳遞的options參數 }, //請求完成後回調函數 (請求成功或失敗以後均調用)。參數: XMLHttpRequest 對象和一個描述成功請求類型的字符串 complete:function(XMLHttpRequest, textStatus) { //this 調用本次AJAX請求時傳遞的options參數 }, //一組數值的HTTP代碼和函數對象,當響應時調用了相應的代碼。例如,若是響應狀態是404,將觸發如下警報: statusCode:{ 404:function(){ alert('404,頁面不存在'); } } });
$.ajax({ type: "POST", url: "https://www.api.com/api/xxx", dataType:'json', data: {id:1},//也能夠是字符串連接"id=1",建議用對象 success: function(data){ console.log("返回的數據: " + data ); } }); 或者 $.post("https://www.api.com/api/xxx",{id:1},function(data){ console.log("返回的數據: " + data ); },'json');
$.ajax({ type: "GET", url: "https://www.api.com/api/xxx", dataType:'json', data: {id:1001},//也能夠是字符串連接"id=1001",建議用對象 success: function(data){ console.log("返回的數據: " + data ); } }); 或者 $.get("https://www.api.com/api/xxx",{id:1},function(data){ console.log("返回的數據: " + data ); },'json');
$("form").on("submit",function(){ var url = this.action; // 能夠直接取到表單的action var formData = $(this).serialize(); // 序列化表單數據 $.post(url,formData,function(data){ //返回成功,能夠作一個其餘事情 console.log(data); },'json'); //阻止表單默認提交行爲 return false })
ajax請求成功一般是使用回調的方式處理返回數據,其實jquery中也可使用連寫方式而不是回調的方式html
// 該參數能夠是一個函數或一個函數的數組。當延遲成功時,done中函數被調用,回調執行是依照他們添加的順序 $.get("https://www.api.com/api/xxx",{id:1}).done(function() { // 返回成功 }).fail(function(){ // 處理失敗; });
$.get("https://www.api.com/api/xxx",{id:1}).then( function(){ //返回成功 }, function(){ // 處理失敗; } );
兩個所有請求成功纔會執行回調, 不然就是失敗,相似於Promise.allvue
$.when($.ajax("p1.php"), $.ajax("p2.php")) .then( function(){ //兩個所有請求成功,才執行 }, function(){ //任何一個執行失敗 } );
$.getScript():jQuery提供了此方法來直接加載js文件,與加載一個HTML片斷同樣簡單方便,而且不須要對JavaScript文件進行處理,JavaScript文件會自動執行node
$.getJSON('test.json', function(data) { // 獲取文件成功的回調 });
load() 方法經過 AJAX 請求從服務器加載數據,並把返回的數據放置到指定的元素中jquery
$('#result').load('ajax/test.html', function() { alert('Load was performed.'); }); //.load() 方法,與 $.get() 不一樣,容許咱們規定要插入的遠程文檔的某個部分。這一點是經過 url 參數的特殊語法實現的。若是該字符串中包含一個或多個空格,緊接第一個空格的字符串則是決定所加載內容的 jQuery 選擇器 // 若是test.html接口返回的是個html,則會插入到#container元素中 $('#result').load('ajax/test.html #container');
特性ios
APIgit
全局github
axios.request(config)
最終http請求都是執行這個方法axios(config)
和axios.request()等價axios(url[, config])
axios(config)快捷方式axios.[METHODS](url, config)
axios(config)快捷方式自定義實例ajax
axios.create(config)
自定義配置,建立實例instance。調用方式和axios方法一致攔截器json
axios.interceptors.request.use
axios.interceptors.response.use
常見用法
配置優先級:lib/default.js中的庫默認值 -->實例的config屬性--> 請求的config參數
// 全局調用 axios({ method:'get', url:'https://www.api.com/api/xxx', field: 123 }) // axios(config) axios('http://bit.ly/2mTM3nY', {field: 123}) // axios(url[, config]) axios.get('http://bit.ly/2mTM3nY', {field: 123}) // axios.[METHODS](url, config) // 自定義實例調用 const instance = axios.create({ baseURL: 'https://www.api.com/api/xxx' }); instance({ method:'get', url:'2mTM3nY', field: 123 }) // instance(config) instance.get('2mTM3nY', {field: 123}) // instance.[METHODS](url, config)
源碼在lib/default.js中
function createInstance(defaultConfig) { var context = new Axios(defaultConfig); // instance指向了request方法,且上下文指向context // instance(config) = Axios.prototype.request(config) var instance = bind(Axios.prototype.request, context); // 把Axios.prototype上的方法擴展到instance對象上 // 這樣 instance 就有了 get、post、put等METHOD方法 // 同時指定上下文爲context,這樣執行Axios原型鏈上的方法時,this會指向context utils.extend(instance, Axios.prototype, context); // 把context對象上的自身屬性和方法擴展到instance上 utils.extend(instance, context); return instance; } // 導出時就建立一個默認實例,因此能夠經過axios(config)發出請求 var axios = createInstance(defaults); axios.Axios = Axios; // 工廠模式建立axios實例,其實最終都是調用createInstance方法。 // 因此實例調用方式和全局axios調用方式相同。instance(config) = axios(config) axios.create = function create(instanceConfig) { return createInstance(mergeConfig(axios.defaults, instanceConfig)); }; module.exports = axios; module.exports.default = axios; // 容許在ts中導入
重點是createInstance
方法,該方法拿到一個Function,該Function指向請求入口Axios.prototype.request,而且該Function還繼承了Axios.prototype的每一個方法,而且上下文指向同一個對象context。axios包默認導出是該Function,而自定義實例axios.create是一個工廠模式,最終都調用createInstance方法。
請求流程實質上無非就是輸入和輸出,輸入request config配置(如url、method、data等),輸出最終的response data數據。中間涉及到較多的數據預處理,如根據data數據類型(如JSON),設置Content-Type: json頭信息;再如根據響應的數據類型,默認轉換爲json格式。這些預處理須要axios庫自動完成,同時也要暴露出相關配置給開發者,以此實現開發者自定義預處理。
Axios經過攔截者(Interceptors)來實現上面說的數據預處理,具體經過使用chain鏈式來逐一插入處理邏輯。默認狀況下,先拿到這次請求的config配置,把config做爲參數,傳遞到dispatchRequest
方法中,該方法會根據當前環境(Browser/Node)來調用不一樣的adapter發送請求,以此得到最終的response data。同時Axios還容許使用request/response Interceptors進行請求前和響應後的自定義處理,其實質是將預處理函數,插入chain數組中,再統一按照順序逐步執行預處理方法(Promise保證順序)。
Axios類是核心內容,該類request方法是全部請求的開始入口。源碼在lib/core/Axios.js:
Axios.prototype.request = function request(config) { // 1. 容許 axios('url'[, config]) = axios(config) if (typeof config === 'string') { config = arguments[1] || {}; config.url = arguments[0]; } else { config = config || {}; } // 配置文件合併策略優先級 config = mergeConfig(this.defaults, config); config.method = config.method ? config.method.toLowerCase() : 'get'; // 2. 定義攔截器中間件鉤子 // dispatchRequest是真正開始下發請求,執行config中設置的adapter方法 var chain = [dispatchRequest, undefined]; var promise = Promise.resolve(config); // 添加請求前鉤子 this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { chain.unshift(interceptor.fulfilled, interceptor.rejected); }); // 添加請求後鉤子 this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { chain.push(interceptor.fulfilled, interceptor.rejected); }); // 3. chain鏈關鍵代碼,promise鏈路傳遞下去 while (chain.length) { promise = promise.then(chain.shift(), chain.shift()); } return promise; }; // 提供對request方法的METHOD快捷方式,實質都是調用Axios.prototype.request方法 // axios.get(url, config) = axios(config) utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { Axios.prototype[method] = function(url, config) { return this.request(utils.merge(config || {}, { method: method, url: url })); }; }); utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { Axios.prototype[method] = function(url, data, config) { return this.request(utils.merge(config || {}, { method: method, url: url, data: data })); }; });
請看我發表一篇《vue+axios+promise實際開發用法》,詳細介紹具體用法
Fetch API 是近年來被說起將要取代XHR
的技術新標準,是一個 HTML5 的 API。
Fetch 並非XHR
的升級版本,而是從一個全新的角度來思考的一種設計。Fetch 是基於 Promise 語法結構,並且它的設計足夠低階,這表示它能夠在實際需求中進行更多的彈性設計。對於XHR所提供的能力來講,Fetch 已經足夠取代XHR
,而且提供了更多拓展的可能性。
// 獲取 some.json 資源 fetch('some.json') .then(function(response) { return response.json(); }) .then(function(data) { console.log('data', data); }) .catch(function(error) { console.log('Fetch Error: ', error); }); // 採用ES2016的 async/await 語法 async function() { try { const response = await fetch('some.json'); const data = response.json(); console.log('data', data); } catch (error) { console.log('Fetch Error: ', error) } }
fetch('https://www.api.com/api/xxx', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }, body: 'a=1&b=2', }).then(resp => resp.json()).then(resp => { console.log(resp) });
fetch('https://www.api.com/api/xxx?location=北京&key=bc08513d63c749aab3761f77d74fe820',{ method:'GET' }) // 返回一個Promise對象 .then((res)=>{ return res.json(); }) .then((res)=>{ console.log(res) // res是最終的結果 })
fetch('https://www.api.com/api/xxx') .then(response => response.text()) .then(data => console.log(data));
var headers = new Headers({ "Content-Type": "text/plain", "X-Custom-Header": "aaabbbccc", }); var formData = new FormData(); formData.append('name', 'lxa'); formData.append('file', someFile); var config = { credentials: 'include', // 支持cookie headers: headers, // 自定義頭部 method: 'POST', // post方式請求 body: formData // post請求攜帶的內容 }; fetch('https://www.api.com/api/xxx', config) .then(response => response.json()) .then(data => console.log(data)); // 或者這樣添加頭部 var content = "Hello World"; var myHeaders = new Headers(); myHeaders.append("Content-Type", "text/plain"); myHeaders.append("Content-Length", content.length.toString()); myHeaders.append("X-Custom-Header", "ProcessThisImmediately");
GET
,POST
。Blob
,BufferSource
,FormData
,URLSearchParams
或者USVString
。注意,GET
,HEAD
方法不能包含body。mode: 請求模式,分別有cors
,no-cors
,same-origin
,navigate
這幾個可選值。
Acess-Control-Allow-Origin
這樣的頭部表示容許跨域。HEAD
,GET
,POST
方法。credentials: 表示是否發送cookie
,有三個選項
cookie
。cookie
。cookie
。redirect: 表示發生重定向時,有三個選項
var URL = 'https://www.api.com/api/xxx'; // 實例化 Headers var headers = new Headers({ "Content-Type": "text/plain", "Content-Length": content.length.toString(), "X-Custom-Header": "ProcessThisImmediately", }); var getReq = new Request(URL, {method: 'GET', headers: headers }); fetch(getReq).then(function(response) { return response.json(); }).catch(function(error) { console.log('Fetch Error: ', error); });