有時候不想使用axios這樣的外部依賴,想自己封裝ajax,這里有兩種方法
方法一,在單個頁面內使用
封裝的代碼如下:
beforeCreate () {
this.$http = (() => {
let createFetch = (type, url, params) => {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4){
if(xhr.status === 200){
var res = xhr.responseText;
try {
res = JSON.parse(xhr.responseText)
} catch (e) {}
resolve(res)
} else {
reject(xhr.responseText)
}
}
}
url += url.includes('?') ? '&' : '?'
if (type === 'GET') {
let serialArr = []
Object.keys(params).forEach(v => {
serialArr.push(`${v}=${params[v]}`)
})
url += serialArr.join('&')
}
xhr.withCredentials = true; //支持跨域發送cookies
xhr.open(type, url, true);
xhr.send(type === 'GET' ? null : params);
})
}
return {
get: (...args) => createFetch("GET", args[0], args[1]),
post: (...args) => createFetch("POST", args[0], args[1])
}
})()
}
使用的代碼如下:
this.$http.get('http://123.103.9.204:6058/official/rest/document/wenku/1/3293036/groupList', {pageSize: '1', pageSize: 30, groupType: 0}).then((res)=>{
if(res.flag == 0){
this.requestData = res.data
}
})
方法二,全局注冊
封裝的方法如下:
export default
{
install(Vue)
{
Vue.prototype.$http=function(options){
/*將數據轉化為字符串*/
var strData=function(data){
var dataStr="";
for(var key in data){
dataStr += key+'='+data[key]+'&';
}
dataStr = dataStr && dataStr.slice(0,-1);
return dataStr;
};
/*創建 XMLHttpRequest 對象*/
var createXHR=function(){
var xhr;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xhr=new XMLHttpRequest();
}
else {// code for IE6, IE5
xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
return xhr
};
/*向服務器發送請求*/
var open=function(xhr,type,url,async){
xhr.open(type,url,async);
};
var send=function(xhr,msg){
xhr.send(msg);
};
var setHeaders=function(xhr,headers){
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
if(!headers){
return false;
}
for(var key in headers){
xhr.setRequestHeader(key,headers[key]);
}
}
var request=function(xhr,opts){
if(opts.type==="GET"){
open(xhr,opts.type,opts.url+'?'+strData(opts.data),opts.async);
send(xhr,null);
}
else if(opts.type==="POST"){
open(xhr,opts.type,opts.url,opts.async);
if(opts.headers){
setHeaders(xhr,opts.headers);
}
send(xhr,strData(opts.data));
}
};
return new Promise((resolve,reject)=>{
if(!options || typeof options != 'object'){
reject(new Error("參數錯誤,請傳入對象參數!"));
return false;
}
if(!options.url){
reject(new Error("url不能為空"));
return false;
}
options.type = options.type?options.type.toUpperCase():'GET';
options.async = (options.async && options.async === false)?false:true;
options.dataType = options.dataType || "json";
options.data = options.data || {};
options.headers = options.headers || {};
var dataStr=strData(options.data);
/*創建 XMLHttpRequest 對象*/
var xhr=createXHR();
/*創建服務器返回響應后執行操作函數*/
xhr.onreadystatechange=function(){
var responseData;
if(xhr.readyState == 4){
switch (xhr.status){
case 200:
switch (options.dataType){
case "xml":
responseData=xhr.responseXML;
break;
case "text":
responseData = xhr.responseText;
break;
case "json":
responseData = JSON.parse(xhr.responseText);
break;
}
resolve(responseData);
default:
reject(new Error("這里做錯誤處理"));
}
}
};
/*向服務器發送請求*/
request(xhr,options);
})
};
Vue.prototype.$post=function(options){
options.type='post';
return this.$http(options);
};
Vue.prototype.$get=function(options){
options.type='get';
return this.$http(options);
};
}
}
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import Install from './install/index.js'
// 這里全局安裝
Vue.use(Install)
new Vue({
el: '#app',
router,
render: h => h(App)
})
使用的代碼如下:
var reuestData = {
url: "http://123.103.9.204:6058/official/rest/document/wenku/1/3293036/groupList",
data: {pageSize: '1', pageSize: 30, groupType: 0}
}
this.$get(reuestData).then((res)=>{
if(res.flag == 0) {
this.requestData = res.data
}
})
兩種方法的比較:
方法一的每個頁面要想使用, 都需要寫相關的代碼,而且由於使用了匿名函數立即執行,如果函數內部有錯誤,不好調試
方法二使用了全局注冊,只要在main.js 注冊了全局都可以使用。