qs庫使用
介紹
axios 默認(rèn)使用的是 content-type 是 application/json , 也就是后端經(jīng)常讓你把參數(shù)放在 body
中的那種格式关炼,傳輸?shù)臉邮绞?/p>
requestbody
{
name:xxx,
age:xxx
}
如果使用的qs進(jìn)行系列化择懂,那 content-type 就是 application/x-www-form-urlencoded媳瞪,也就是常說的表單提交腰根,傳輸?shù)臉邮绞?br> formdata
name:xxx,
age:xxx
urlencoding 后是 name=xxx&age=xxx
安裝
npm install qs
或
yarn add qs
使用
方法: stringify()
var obj = {
a: "kingEND",
b: "bname"
}
var res = qs.stringify(obj)
console.log(res) // a="kingEND"&b="bname"
方法: parse()
var url = 'method=query_sql_dataset_data&projectId=85& appToken=7d22e38e-5717-11e7-907b-a6006ad3dba0';
var res = qs.parse(url);
console.log(res)
//{
// method: "query_sql_dataset_data",
// projectId: "85",
// appToken: "7d22e38e-5717-11e7-907b-a6006ad3dba0"
//}
AXios 的詳細(xì)配置
{
// `url` 是用于請(qǐng)求的服務(wù)器 URL
url: '/user',
// `method` 是創(chuàng)建請(qǐng)求時(shí)使用的方法
method: 'get', // 默認(rèn)是 get
// `baseURL` 將自動(dòng)加在 `url` 前面,除非 `url` 是一個(gè)絕對(duì) URL杉允。
// 它可以通過設(shè)置一個(gè) `baseURL` 便于為 axios 實(shí)例的方法傳遞相對(duì) URL
baseURL: 'https://some-domain.com/api/',
// `transformRequest` 允許在向服務(wù)器發(fā)送前终蒂,修改請(qǐng)求數(shù)據(jù)
// 只能用在 'PUT', 'POST' 和 'PATCH' 這幾個(gè)請(qǐng)求方法
// 后面數(shù)組中的函數(shù)必須返回一個(gè)字符串,或 ArrayBuffer签则,或 Stream
transformRequest: [function (data) {
// 對(duì) data 進(jìn)行任意轉(zhuǎn)換處理
return data;
}],
// `transformResponse` 在傳遞給 then/catch 前须床,允許修改響應(yīng)數(shù)據(jù)
transformResponse: [function (data) {
// 對(duì) data 進(jìn)行任意轉(zhuǎn)換處理
return data;
}],
// `headers` 是即將被發(fā)送的自定義請(qǐng)求頭
headers: {'X-Requested-With': 'XMLHttpRequest'},
// `params` 是即將與請(qǐng)求一起發(fā)送的 URL 參數(shù)
// 必須是一個(gè)無格式對(duì)象(plain object)或 URLSearchParams 對(duì)象
params: {
ID: 12345
},
// `paramsSerializer` 是一個(gè)負(fù)責(zé) `params` 序列化的函數(shù)
// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
paramsSerializer: function(params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
},
// `data` 是作為請(qǐng)求主體被發(fā)送的數(shù)據(jù)
// 只適用于這些請(qǐng)求方法 'PUT', 'POST', 和 'PATCH'
// 在沒有設(shè)置 `transformRequest` 時(shí),必須是以下類型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 瀏覽器專屬:FormData, File, Blob
// - Node 專屬: Stream
data: {
firstName: 'Fred'
},
// `timeout` 指定請(qǐng)求超時(shí)的毫秒數(shù)(0 表示無超時(shí)時(shí)間)
// 如果請(qǐng)求話費(fèi)了超過 `timeout` 的時(shí)間渐裂,請(qǐng)求將被中斷
timeout: 1000,
// `withCredentials` 表示跨域請(qǐng)求時(shí)是否需要使用憑證
withCredentials: false, // 默認(rèn)的
// `adapter` 允許自定義處理請(qǐng)求侨颈,以使測(cè)試更輕松
// 返回一個(gè) promise 并應(yīng)用一個(gè)有效的響應(yīng) (查閱 [response docs](#response-api)).
adapter: function (config) {
/* ... */
},
// `auth` 表示應(yīng)該使用 HTTP 基礎(chǔ)驗(yàn)證,并提供憑據(jù)
// 這將設(shè)置一個(gè) `Authorization` 頭芯义,覆寫掉現(xiàn)有的任意使用 `headers` 設(shè)置的自定義 `Authorization`頭
auth: {
username: 'janedoe',
password: 's00pers3cret'
},
// `responseType` 表示服務(wù)器響應(yīng)的數(shù)據(jù)類型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
responseType: 'json', // 默認(rèn)的
// `xsrfCookieName` 是用作 xsrf token 的值的cookie的名稱
xsrfCookieName: 'XSRF-TOKEN', // default
// `xsrfHeaderName` 是承載 xsrf token 的值的 HTTP 頭的名稱
xsrfHeaderName: 'X-XSRF-TOKEN', // 默認(rèn)的
// `onUploadProgress` 允許為上傳處理進(jìn)度事件
onUploadProgress: function (progressEvent) {
// 對(duì)原生進(jìn)度事件的處理
},
// `onDownloadProgress` 允許為下載處理進(jìn)度事件
onDownloadProgress: function (progressEvent) {
// 對(duì)原生進(jìn)度事件的處理
},
// `maxContentLength` 定義允許的響應(yīng)內(nèi)容的最大尺寸
maxContentLength: 2000,
// `validateStatus` 定義對(duì)于給定的HTTP 響應(yīng)狀態(tài)碼是 resolve 或 reject promise 妻柒。如果 `validateStatus` 返回 `true` (或者設(shè)置為 `null` 或 `undefined`)扛拨,promise 將被 resolve; 否則,promise 將被 rejecte
validateStatus: function (status) {
return status >= 200 && status < 300; // 默認(rèn)的
},
// `maxRedirects` 定義在 node.js 中 follow 的最大重定向數(shù)目
// 如果設(shè)置為0举塔,將不會(huì) follow 任何重定向
maxRedirects: 5, // 默認(rèn)的
// `httpAgent` 和 `httpsAgent` 分別在 node.js 中用于定義在執(zhí)行 http 和 https 時(shí)使用的自定義代理绑警。允許像這樣配置選項(xiàng):
// `keepAlive` 默認(rèn)沒有啟用
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
// 'proxy' 定義代理服務(wù)器的主機(jī)名稱和端口
// `auth` 表示 HTTP 基礎(chǔ)驗(yàn)證應(yīng)當(dāng)用于連接代理求泰,并提供憑據(jù)
// 這將會(huì)設(shè)置一個(gè) `Proxy-Authorization` 頭,覆寫掉已有的通過使用 `header` 設(shè)置的自定義 `Proxy-Authorization` 頭计盒。
proxy: {
host: '127.0.0.1',
port: 9000,
auth: : {
username: 'mikeymike',
password: 'rapunz3l'
}
},
// `cancelToken` 指定用于取消請(qǐng)求的 cancel token
// (查看后面的 Cancellation 這節(jié)了解更多)
cancelToken: new CancelToken(function (cancel) {
})
Axios 請(qǐng)求中斷
需求分析
在項(xiàng)目中經(jīng)常有一些場景會(huì)連續(xù)發(fā)送多個(gè)請(qǐng)求渴频,而異步會(huì)導(dǎo)致最后得到的結(jié)果不是我們想要的,并且對(duì)性能也有非常大的影響北启。例如一個(gè)搜索框卜朗,每輸入一個(gè)字符都要發(fā)送一次請(qǐng)求,但輸入過快的時(shí)候其實(shí)前面的請(qǐng)求并沒有必要真的發(fā)送出去咕村,這時(shí)候就需要在發(fā)送新請(qǐng)求的時(shí)候直接取消上一次請(qǐng)求场钉。
取消接口請(qǐng)求
Axios 提供了一個(gè) CancelToken的函數(shù),這是一個(gè)構(gòu)造函數(shù)懈涛,該函數(shù)的作用就是用來取消接口請(qǐng)求的逛万。
<body>
<div class="page" id="app">
<button @click="getMsg" class="get-msg">獲取數(shù)據(jù)</button>
<button @click="cancelGetMsg" class="cancel">取消獲取</button>
<ul>
<li v-for="item in items">{{item.name}}</li>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
items: [],
cancel: null
},
methods: {
getMsg () {
let CancelToken = axios.CancelToken
let self = this
axios.get('http://jsonplaceholder.typicode.com/comments', {
cancelToken: new CancelToken(function executor(c) {
self.cancel = c
console.log(c)
// 這個(gè)參數(shù) c 就是CancelToken構(gòu)造函數(shù)里面自帶的取消請(qǐng)求的函數(shù),這 里把該函數(shù)當(dāng)參數(shù)用
})
}).then(res => {
this.items = res.data
}).catch(err => {
console.log(err)
})
//手速夠快就不用寫這個(gè)定時(shí)器了批钠,點(diǎn)擊取消獲取就可以看到效果了
setTimeout(function () {
//只要我們?nèi)フ{(diào)用了這個(gè)cancel()方法宇植,沒有完成請(qǐng)求的接口便會(huì)停止請(qǐng)求
self.cancel()
}, 100)
},
//cancelGetMsg 方法跟上面的setTimeout函數(shù)是一樣的效果,因?yàn)槭炙俨粔蚩欤? 哦不埋心,是因?yàn)榫W(wǎng)速太快指郁,導(dǎo)致我來不及點(diǎn)取消獲取按鈕,數(shù)據(jù)就獲取成功了
cancelGetMsg () {
// 在這里去判斷你的id 1 2 3踩窖,你默認(rèn)是展示的tab1坡氯,點(diǎn)擊的時(shí)候不管你上一 個(gè)請(qǐng)求有沒有執(zhí)行完都去調(diào)用這個(gè)cancel(),
this.cancel()
}
}
})
</script>
</body>
重復(fù)點(diǎn)擊問題
我們經(jīng)常開發(fā)的時(shí)候會(huì)遇到一個(gè)重復(fù)點(diǎn)擊的問題洋腮,短時(shí)間內(nèi)多次點(diǎn)擊同一個(gè)按鈕發(fā)送請(qǐng)求會(huì)加重服務(wù)器的負(fù)擔(dān)箫柳,消耗瀏覽器的性能,多以絕大多數(shù)的時(shí)候我們需要做一個(gè)取消重復(fù)點(diǎn)擊的操作
在vue開發(fā)中啥供,這個(gè)方法一樣完美解決這一問題悯恍,通常我們會(huì)封裝一遍axios,這里我們便可以將此功能封裝到攔截器里面去
import axios from 'axios';
axios.defaults.timeout = 5000;
axios.defaults.baseURL ='';
let pending = []; //聲明一個(gè)數(shù)組用于存儲(chǔ)每個(gè)ajax請(qǐng)求的取消函數(shù)和ajax標(biāo)識(shí)
let cancelToken = axios.CancelToken;
let removePending = (ever) => {
for(let p in pending){
if(pending[p].u === ever.url + '&' + ever.method) { //當(dāng)當(dāng)前請(qǐng)求在數(shù)組中存在時(shí)執(zhí)行函數(shù)體
pending[p].f(); //執(zhí)行取消操作
pending.splice(p, 1); //把這條記錄從數(shù)組中移除
}
}
}
//http request 攔截器
axios.interceptors.request.use(
config => {
config.data = JSON.stringify(config.data);
config.headers = {
'Content-Type':'application/x-www-form-urlencoded'
}
// -------------------------------------------------------------------------
removePending(config); //在一個(gè)ajax發(fā)送前執(zhí)行一下取消操作
config.cancelToken = new cancelToken((c)=>{
// 這里的ajax標(biāo)識(shí)我是用請(qǐng)求地址&請(qǐng)求方式拼接的字符串伙狐,當(dāng)然你可以選擇其他的一些方式
pending.push({ u: config.url + '&' + config.method, f: c });
});
// -------------------------------------------------------------------------------
return config;
},
error => {
return Promise.reject(err);
}
);
//http response 攔截器
axios.interceptors.response.use(
response => {
// -----------------------------------------------------------------------------
removePending(res.config); //在一個(gè)ajax響應(yīng)后再執(zhí)行一下取消操作涮毫,把已經(jīng)完成的請(qǐng)求從pending中移除
// ----------------------------------------------------------------------------
if(response.data.errCode ==2){
router.push({
path:"/login",
querry:{redirect:router.currentRoute.fullPath}//從哪個(gè)頁面跳轉(zhuǎn)
})
}
return response;
},
error => {
return Promise.reject(error)
}
)