一,Content-Type
首先要明確的一點是,我們在項目中調用接口,通常是以對象的數(shù)據(jù)格式傳給自己封裝的http請求函數(shù)的。
1,application/json
現(xiàn)在的前后端分離項目基本上都是使用的這個進行數(shù)據(jù)傳遞。
axios默認Content-type是采用application/json;charset=UTF-8,無需設置直接把對象傳進去即可
當然,也可以在請求攔截器中轉化成json后再發(fā)請求(但是不能用qs.stringify):
config.data = JSON.stringify(config.data)
2,application/x-www-form-urlencoded
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
用于表單的提交。值得注意的是,ajax 中(不是axios哈), contentType都是默認的值:application/x-www-form-urlencoded。
特點是提交的參數(shù)按照 key1=val1&key2=val2 的方式進行編碼,key 和 val 會進行了 URL 轉碼。
而要實現(xiàn)這種參數(shù)的序列化,最簡單的方法是引入qs庫。做如下的配置。
import Qs from "qs"
// 創(chuàng)建axios實例
const service = axios.create({
baseURL: process.env.VUE_APP_baseUrl,
timeout: 5000,
...//其他配置
//transformRequest用來對請求參數(shù)提前進行處理
transformRequest: [data => Qs.stringify(data, { indices: true })] //Qs.stringify將參數(shù)序列化成key=value&key=value的形式,indices: true是配置參數(shù)有傳數(shù)組的時候,以下標的形式
})
比如說,當我們傳遞的參數(shù)是:
{
title:'標題',
list:[1,2,3]
}
則會被轉化成:title=標題&list[0]=1&list[1]=2&list[2]=3的形式。
Qs.stringify(data, { indices: true }//這個如果用false的話。傳數(shù)組就是title=標題&list=1&list=2&list=3的形式了,也就是不帶索引。
結合上文,在content-tyoe=application/x-www-form-urlencoded時,我們在頁面中傳的是對象,然后通過Qs.stringify把參數(shù)轉換成key=value的形式了,這才可以發(fā)出正確的http請求。
另外,Qs.stringify配置的場合也可以有多個。如下圖在axios中進行配置。
3,multipart/form-data
這也是一個常見的 POST 數(shù)據(jù)提交的方式。我們使用表單上傳文件時,就要讓 form 的 enctype 等于這個值。這種方式一般用來上傳文件,各大服務端語言對它也有著良好的支持。這個和application/x-www-form-urlencoded的區(qū)別在于一個適合傳字段鍵值,一個適合傳文件。
二,qs.sringify和JSON.stringify的區(qū)別
假設我要提交的數(shù)據(jù)是:
var a = {name:'hehe',age:10};
qs.stringify序列化結果如下
name=hehe&age=10
而JSON.stringify序列化結果如下:
"{"a":"hehe","age":10}"
三,項目中的實際應用
這個項目呢,大多數(shù)post請求,后端的接口設計的是application/x-www-form-urlencoded類型的content-type。唯獨有一個接口設計的是application/json。但是我最開始content-type的設置是在全局的axios中進行配置的,全都配置成application/x-www-form-urlencoded。于是需要分類下,使用application/x-www-form-urlencoded的時候,需要key-value序列化處理,而另一種application/json的則不需要。
import axios from "axios"
import { Message as showMessage } from "element-ui"
import errorCode from "./errorCode"
// import store from "@/store"
import Qs from "qs"
// axios.defaults.headers["Content-Type"] = "application/json" //底下創(chuàng)建axios實例時配置了,這個不用重復配置,再說,這也是axios的默認配置
export default function request(options) {
return new Promise((resolve, reject) => {
// 創(chuàng)建axios實例
const service = axios.create({
// 表示請求URL公共部分,它會讀取這里的值,然后拼接上頁面使用的url
baseURL: process.env.VUE_APP_baseUrl,
timeout: 5000,
withCredentials: false, // 跨域請求時是否需要cookie等憑證
responseType: "json",
params: {},
maxContentLength: 2000,
validateStatus: status => status >= 200 && status < 300, //默認值
maxRedirects: 5, //最大允許重定向次數(shù)
headers: {
//公共請求頭配置,本項目請求頭大多數(shù)接口是這個,所以這里可以配置一下,對于特殊接口單獨配置
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
}
// transformRequest: [data => Qs.stringify(data, { indices: true })] //將參數(shù)key=value序列化,因為本項目有的接口需要json/對象傳參數(shù),這里就不能這樣直接全局配置,否則有的接口會報400(因為你把json或者是對象類型的數(shù)據(jù),在這里key=value序列化了)
})
// request攔截器
service.interceptors.request.use(
config => {
switch (config.method) {
case "get":
if (!config.params) {
config.params = {}
}
break
case "post":
if (!config.data) {
config.data = {}
}
if (config.type === "keyValue") {
config.data = Qs.stringify(config.data) //配套application/x-www-form-urlencoded使用
} else {
config.headers["Content-Type"] = "application/json" //配套application/json使用
}
break
default:
}
console.log(`【request】url:${config.url},data:${config.data} `)
return config
},
error => {
console.log(error)
Promise.reject(error)
}
)
// 響應攔截器
service.interceptors.response.use(
res => {
// 未設置狀態(tài)碼則默認成功狀態(tài)
const code = parseInt(res.data.code) || 0
// 獲取錯誤信息
const msg = res.data.msg || errorCode[code] || errorCode["default"]
if (code != 0) {
showMessage({
message: msg,
type: "error"
})
reject(new Error(msg))
return
} else {
resolve(res.data) //獲取到成功的響應了,就把結果resolve出去
}
},
error => {
console.log("err" + error)
let { message } = error
if (message == "Network Error") {
message = "網(wǎng)絡異常,請檢查網(wǎng)絡"
} else if (message.includes("timeout")) {
message = "系統(tǒng)接口請求超時,請檢查網(wǎng)絡"
} else if (message.includes("Request failed with status code")) {
message = "系統(tǒng)接口" + message.substr(message.length - 3) + "異常"
}
showMessage({
message: message,
type: "error",
duration: 5 * 1000
})
return reject(error)
}
)
service(options)
})
}
然后請求的封裝:
import request from "./request.js"
import { Loading } from "element-ui"
let http = {
/** post 請求
* @param {接口地址} url
* @param {請求參數(shù)} params
* @param {請求的參數(shù)處理類型}
* keyValue:默認的application/x-www-form-urlencoded,使用qs.stringify序列化。
* json:使用application/json,不用處理參數(shù)
*/
post: function (url, params, type = "keyValue") {
let loadingInstance = Loading.service({
lock: true,
text: "請稍候",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
fullscreen: false,
customClass: "loadingClass"
})
return new Promise((resolve, reject) => {
request({
url,
method: "post",
data: params,
type
})
.then(response => {
loadingInstance.close()
resolve(response)
})
.catch(error => {
loadingInstance.close()
reject(error)
})
})
}
}
export default http
頁面中使用application/json的接口的調用:文章來源:http://www.zghlxwxcb.cn/news/detail-406069.html
async newDog() {
const that = this
let params = {
...this.petForm
}
try {
let res = await that.$http.post("/dog/newDog", params, "json")
console.log("--接口請求成功--", res)
that.$message({
message: "接口請求成功",
type: "success"
})
} catch (err) {
console.log("報錯了:", err)
}
},
大致的設計思路:文章來源地址http://www.zghlxwxcb.cn/news/detail-406069.html
到了這里,關于axios請求頭設置常見Content-Type和對應參數(shù)的處理的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!