由於請求頭 content-type爲application/json導致請求出錯

preface

最近在寫 react 項目, 然後調用後臺接口的時候總是報錯, 我本以爲是後臺接口的問題

後來後臺說 請求體 不能爲 null

然後就簡單做了總結

請求頭 content-type 一般使用的兩種格式

application/json

在該種格式情況下, 請求體不能爲 null , 應是一個 json 字符串, 如果沒有數據就加一個 {}

因爲最近一直在開發小程序, 應該是底層做了處理, 所以 同樣的情況,沒有報錯,導致出現問題,一時間沒有反應過來

application/www-from-urlencoded

post 請求 queryString 的方式, 請求頭爲該類型

封裝請求 實戰

一般默認的 content-type application/json

axios

  1. 默認的 content-type application/json
  2. 我們在使用 axios 的時候,可以在導航守衛中 判斷 params 是否存在, 存在則修改請求頭 爲 www-form-urlencoded

下面是封裝的 axios 請求

import axios, { AxiosRequestConfig } from 'axios'
import { baseURL, TokenName } from '@/constants'
import { getToken } from '@/utils'
import { Toast, Dialog } from 'vant'

class RequestError extends Error {
  public msg: string
  public code: string
  public statusCode: number
  public name: string

  public constructor(statusCode: number, code: string, msg: string) {
    super()
    this.msg = msg
    this.code = code
    this.statusCode = statusCode
    this.name = 'RequestError'
  }
}

function unAuthTologin(): void {
  // 跳轉到某個頁面即可

}

function defaultHandler(reqError: RequestError) {
  let msg = reqError.msg
  if (!msg) {
    switch (reqError.statusCode) {
      case 400: msg = '請求錯誤(400)'; break
      case 401:
        msg = '授權已經失效,請重新掃碼領券!'
        // unAuthTologin()
        break
      case 403: msg = '拒絕訪問(403)'; break
      case 404: msg = '請求出錯(404)'; break
      case 408: msg = '請求超時(408)'; break
      case 500: msg = '服務器錯誤(500)'; break
      case 501: msg = '服務未實現(501)'; break
      case 502: msg = '網絡錯誤(502)'; break
      case 503: msg = '服務不可用(503)'; break
      case 504: msg = '網絡超時(504)'; break
      case 505: msg = 'HTTP版本不受支持(505)'; break
      default: msg = `連接出錯(${reqError.statusCode})!`
    }
  }
  // 錯誤提示
  Dialog.alert({
    title: '提示',
    message: msg
  })

  // Message.error({ message: msg })
}

const service = axios.create({
  baseURL,
  timeout: 2000,
  method: 'POST' // 默認 post 請求
})

service.interceptors.request.use((config: AxiosRequestConfig) => {
  const token = getToken()
  token && (config.headers[TokenName] = token)
  config.__loading = config.__loading || true
  if (config.method === 'post') {
    config.headers['content-type'] && !config.data && (config.data = {})
    config.params && !config.headers['content-type'] && (config.headers['content-type'] = 'application/x-www-form-urlencoded')
  }

  if (config.__loading) { // 默認加載 loading
    // loading 效果
    config.__toast = Toast.loading({
      message: '加載中...',
      forbidClick: true,
      loadingType: 'spinner'
    })
  }

  // !config.loading
  // headers: { 'content-type': 'application/x-www-form-urlencoded' },
  // 1. token
  // 2. loading
  // 3. application/json
  // 4. params  處理
  return config
}, (error) => {
  console.log('error--', error)
  return Promise.reject(error)
})

service.interceptors.response.use(({ config, data }) => {
  config.__toast && config.__toast.close()

  const { retCode, retMsg } = data
  if (!config.businessErrNotTip && retCode && retCode !== '000000') {
    // 錯誤提示
    Dialog.alert({
      title: '提示',
      message: retMsg,
      confirmButtonColor: ''
    })

    return Promise.reject(data)
  }
  return Promise.resolve(data)
}, ({ response, msg: resMsg, config }) => {
  config.__toast && config.__toast.close()
  let msg = ''
  let code = '-1'
  let statusCode

  if (response && response instanceof Object) {
    const { msg: errMsg, code: errCode } = response.data // 這裏字段可能需要修改
    statusCode = response.status
    code = errCode
    msg = errMsg
  } else {
    statusCode = 600
    msg = resMsg || 'Network Error'
  }

  const wrapError = new RequestError(statusCode, code, msg)
  defaultHandler(wrapError)
  return Promise.reject(wrapError)
})

export default service

其中處理了 post 方法 content-type 問題

  if (config.method === 'post') {
    config.headers['content-type'] && !config.data && (config.data = {})
    config.params && !config.headers['content-type'] && (config.headers['content-type'] = 'application/x-www-form-urlencoded')
  }

小程序的請求

  1. 默認的 content-type application/json
  2. params 存在,存在則修改請求頭 爲 www-form-urlencoded

在寫小程序代碼過程中發現這個問題貌似框架幫忙處理了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章