先說一下平時工做的狀況:
平常的工做業務中,與後端數據交互只用了兩種形式,GET
和POST
,寫業務代碼的時候傳的參數都是對象格式{name:'jason',age:27}
,通常都是這樣寫:jquery
Http.get('api/userCenter/bookList.json', { date: '2010', lang: 'en' }).then(function(res) { console.log(res); }) Http.post('api/userCenter/login.json', { mobile: 13821863666, psd: 123123 }).then(function(res) { console.log(this); })
GET
傳輸時,須要把對應的參數拼接在URL的後面;POST
傳輸時,send的數據格式也主要只用到瞭如下三種:angularjs
Content-Type: application/x-www-form-urlencoded
,send(data)中的data數據格式爲"name=jason&age=27"
,此時須要序列化參數對象Content-Type: application/json
,send(data)中的data數據格式爲"{"mobile":13821863666,"psd":123123}"
,此時須要用JSON.stringify()
把參數對象轉換成json字符串FormData
對象,直接send(FormDataObj)便可,此時不須要設置Content-Type
我就針對以上這些應用場景對ajax作了簡單的封裝,代碼以下:ajax
// http.js // note:xhr的兼容寫法 // function XHR() { // if (window.XMLHttpRequest) return new XMLHttpRequest(); // if (window.ActiveXObject) return new ActiveXObject('Microsoft.XMLHTTP'); // return 'Not support XMLHttpRequest!'; // } // 判斷是否爲純對象,好比這種格式 {'name': 'jason'} 是純對象,函數、數組等則不是 function isPlainObject(obj) { return Object.prototype.toString.call(obj) === '[object Object]'; } // 查詢字符串中每一個參數的名稱和值都必須使用 encodeURIComponent() 進行編碼,而後才能放到 URL 的末尾; // 全部名-值對兒都必須由和號 ( & ) 分隔 function addURLParam(url, name, value) { url += (url.indexOf('?') == -1 ? '?' : '&'); url += encodeURIComponent(name) + '=' + encodeURIComponent(value); return url; } /** * Converts an object to x-www-form-urlencoded serialization. * http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/ * @param {Object} obj * @return {String} */ function serialize(obj) { var query = '', name, value, fullSubName, subName, subValue, innerObj, i; for (name in obj) { value = obj[name]; if (value instanceof Array) { for (i = 0; i < value.length; ++i) { subValue = value[i]; fullSubName = name + '[' + i + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += serialize(innerObj) + '&'; } } else if (value instanceof Object) { for (subName in value) { subValue = value[subName]; fullSubName = name + '[' + subName + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += serialize(innerObj) + '&'; } } else if (value !== undefined && value !== null) query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&'; } return query.length ? query.substr(0, query.length - 1) : query; } function ajax(type, url, data, contentType) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); if (type.toUpperCase() === 'GET' && data) { for (key in data) { if (data.hasOwnProperty(key)) { url = addURLParam(url, key, data[key]); } } } /** post傳輸,當傳FormData類型的數據時,不須要設置Content-Type * 當數據格式爲純對象時 * 默認設置'Content-Type'爲'application/x-www-form-urlencoded',對數據進行序列化 * 若是'Content-Type'設置爲'application/json',數據直接傳json字符串 **/ if (type.toUpperCase() === 'POST' && isPlainObject(data)) { if (!contentType || contentType === 'application/x-www-form-urlencoded') { xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); data = serialize(data); } else { xhr.setRequestHeader('Content-Type', 'application/json'); data = JSON.stringify(data); } } xhr.open(type, url, true); xhr.onload = function() { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { var res = JSON.parse(xhr.response); resolve(res); } else { reject(xhr.statusText); } }; xhr.timeout = 10000; xhr.ontimeout = function() { reject('連接超時!') }; xhr.onerror = function() { reject('網絡錯誤!'); }; xhr.onabort = function() { reject('請求取消!'); }; xhr.send(type.toUpperCase() === 'GET' ? null : data); // 若是不須要經過請求主體發送數據,則必須傳入null,由於這個參數對有些瀏覽器來講是必需的 }); } export default { get: function(url, data) { return ajax('GET', url, data); }, post: function(url, data, contentType) { return ajax('POST', url, data, contentType); } }
以後就能夠在其餘文件中使用get
和post
這兩個接口:json
import Http from 'http' Http.get('api/userCenter/bookList.json', { date: '2010', lang: 'en' }).then(function(res) { console.log(res); }) Http.post('api/userCenter/login.json', { mobile: 13821863666, psd: 123123 }).then(function(res) { console.log(this); })
get
的使用形式是Http.get(url, data)
;post
的使用形式是Http.post(url, data, contentType)
,第三個參數contentType
可選,當設置了對應的值時,http.js會對傳入的參數作不一樣格式化的處理。後端