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

在写小程序代码过程中发现这个问题貌似框架帮忙处理了。

GitHub 加速计划 / js / json
18
5
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:3 个月前 )
2134cb94 * change NLOHMANN_JSON_FROM_WITH_DEFAULT to let NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT work with an empty JSON instance * fix ci_static_analysis_clang (ci_clang_tidy) * change NLOHMANN_JSON_FROM_WITH_DEFAULT to let NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT work with an empty JSON instance 10 天前
6057b31d * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * Use ubuntu-latest image to run Valgrind (#4575) * :wrench: use Clang image to run valgrind * :wrench: use Clang image to run valgrind * :wrench: use Clang image to run valgrind * :wrench: use Ubuntu image to run valgrind * Use Clang image to run iwyu (#4574) * :wrench: use Clang image to run iwyu * :wrench: use Clang image to run iwyu * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :wrench: overwork astyle call * :art: format code * :hammer: clean up 11 天前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐