一、建立http例項
const http = axios.create({ // 請求超時時間設定為 30 秒,超過這個時間請求會被終止 timeout: 1000 * 30, // 允許跨域請求時攜帶憑證(如 Cookies) withCredentials: true, // 設定請求頭的 Content-Type 為 application/json; charset=utf-8,表明請求體的格式是 JSON,並指定字元編碼。 headers: { 'Content-Type': 'application/json; charset=utf-8' } })
headers: { 'Content-Type': 'application/json; charset=utf-8' }
設定了請求的內容型別,表明傳送的資料格式為 JSON。這對於伺服器理解請求體中的資料格式至關重要。
透過指定 charset=utf-8
,你還確保了字元編碼正確,尤其是在處理非ASCII字元時。這可以避免因編碼不匹配導致的資料解析錯誤。
如果沒有加上 Content-Type: application/json; charset=utf-8
,伺服器可能無法正確解析請求體中的資料。具體後果包括:
資料解析錯誤:伺服器可能會將請求體當作預設的表單數據處理,從而導致資料無法被正確解析。
請求失敗:一些 API 可能要求明確的
Content-Type
,如果未提供,可能返回錯誤響應,例如 400 Bad Request。字元編碼問題:如果請求體包含非 ASCII 字元,伺服器可能會使用預設的字元編碼(通常是 ISO-8859-1),從而導致亂碼或解析錯誤。
總之,明確設定 Content-Type
有助於確保資料在傳輸過程中的一致性和正確性。
二、配置請求攔截器
http.interceptors.request.use(config => { config.headers['token'] = Vue.cookie.get('token') // 請求頭帶上token return config }, error => { return Promise.reject(error) })
三、配置響應攔截器
http.interceptors.response.use(response => { if (response.data && response.data.code === 401) { // 401, token失效 clearLoginInfo() router.push({ name: 'login' }) } console.log('response',response); // 在這裏檢視響應資訊 return response }, error => { return Promise.reject(error) })
console.log('response',response)的結果
四、請求地址處理
http.adornUrl = (actionName) => { // 非生產環境 && 開啟代理, 介面字首統一使用[/proxyApi/]字首做代理攔截! return (process.env.NODE_ENV !== 'production' && process.env.OPEN_PROXY ? '/proxyApi/' : window.SITE_CONFIG.baseUrl) + actionName }
五、GET請求引數處理
/** * get請求引數處理 * @param {*} params 引數物件 * @param {*} openDefultParams 是否開啟預設引數? */ http.adornParams = (params = {}, openDefultParams = true) => { var defaults = { 't': new Date().getTime() } return openDefultParams ? merge(defaults, params) : params }
新增時間戳 't': new Date().getTime()
的好處:
確保請求的唯一性,避免瀏覽器或伺服器端的快取影響
用於請求的跟蹤和日誌記錄。伺服器可以記錄每次請求的時間戳,這對於分析請求頻率、響應時間等效能指標非常有用
在一定程度上增加表單重複提交的難度
將時間戳等預設引數封裝在函式內部,減少了程式碼冗餘
六、POST請求引數處理
http.adornData = (data = {}, openDefultdata = true, contentType = 'json') => { var defaults = { 't': new Date().getTime() } data = openDefultdata ? merge(defaults, data) : data return contentType === 'json' ? JSON.stringify(data) : qs.stringify(data) }
函式根據 contentType
引數的值來決定如何格式化合並後的資料。如果 contentType
為 'json'
(預設值),則使用 JSON.stringify
方法將物件轉換為JSON格式的字串。如果 contentType
不是 'json'
,則假設是表單資料(application/x-www-form-urlencoded
或 multipart/form-data
),並使用 qs.stringify
方法(這裏假設 qs
是一個查詢字串(query string)解析和字串化庫,如qs
npm包)將物件轉換為查詢字串格式的字串。
七、將http例項掛載全域性
在vue專案的main.js中
import httpRequest from '@/utils/httpRequest' Vue.prototype.$http = httpRequest
八、使用get方法
async getMarketList() { this.$http({ url: this.$http.adornUrl('/xxx/xxx/xxxxxxxxx'), method: 'get' }).then(({ data }) => { if (data && data.code === 0) { this.marketList = data.data // console.log('this.marketList', this.marketList) } else { this.marketList = [] } }) },
九、使用post方法
// 提交表單 dataFormSubmit() { // console.log(Encrypt(this.dataForm.password)); this.$refs['dataForm'].validate((valid) => { if (valid) { this.$http({ url: this.$http.adornUrl('/xxxx/login'), method: 'post', data: this.$http.adornData({ 'username': this.dataForm.userName, 'password': Encrypt(this.dataForm.password), 'uuid': this.dataForm.uuid, 'captcha': this.dataForm.captcha }) }).then(({ data }) => { if (data && data.code === 0) { this.$cookie.set('token', data.token) this.$router.replace({ name: 'home' }) } else { this.getCaptcha() this.$message.error(data.msg) } }) } }) },