Axios 不尊重 Content-Type 标头

Big*_*boy 7 javascript axios

这是我的 axios 配置:

import axios from "axios"

const axiosApi = axios.create({
  baseURL: import.meta.env.VITE_API_URL
})

const requestInterceptor = config => {
  config.headers['Content-Type'] = 'application/json';
  config.headers['Accept'] = 'application/json';
  config.headers['X-Client'] = 'React';
  return config;
}

axiosApi.interceptors.request.use(requestInterceptor);

const get = async (url) => {
  return await
    axiosApi.get(url, {
      crossDomain: true
    }).then(response => {
      return response?.data;
    })
}

const post = async (url, data) => {
  return await axiosApi
    .post(url, Array.isArray(data) ? [...data] : { ...data })
    .then(response => response?.data)
}

const form = async (url, data) => {
  return await axiosApi
    .post(url, data, {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    })
    .then(response => response?.data)
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,对于postget实用程序方法,我使用设置默认值的请求拦截器。Content-Type: application/json因此我为他们使用。

但是,因为form我将Content-Type标题重写为表单。

我读了一些其他问题,包括:

Axios 未传递 Content-Type 标头

未为 safari 设置 Axios 标头的 Content-Type

但我的服务器允许Content-Type在 CORS 请求中发送:

Access-Control-Allow-Headers: authorization,content-type,x-client
Access-Control-Allow-Methods: POST
Access-Control-Allow-Origin: *
Run Code Online (Sandbox Code Playgroud)

但是当我使用form方法时,我发现Content-Type没有设置为application/json, not application/x-www-form-urlencoded

我做错了什么?

Phi*_*hil 7

默认情况下,Axios 具有出色的请求正文处理能力。

  • 如果它看到一个普通的 JavaScript 对象或数组,它会使用application/json.
  • 如果您传入一个纯字符串或 的实例URLSearchParams,它会使用application/x-www-form-urlencoded.
  • 传入一个FormData实例,它将使用multipart/form-data

那么为什么 Stack Overflow 上会出现无穷无尽的关于自定义content-typeheader 的问题呢?我什至认为,除非您的 API 使用正确的内容协商,否则您也不需要弄乱标Accept头。

我认为在你的情况下不需要拦截器。只需在您的实例上设置请求标头默认值

axiosApi.defaults.headers.common["X-Client"] = "React";
// and if your API actually uses content negotiation...
// axiosApi.defaults.headers.common.Accept = "application/json";
Run Code Online (Sandbox Code Playgroud)

至于你的url 编码请求,Axios 0.x 通过URLSearchParams或纯字符串支持这种方式。它不会自动将普通对象转换为application/x-www-form-urlencoded.

如果你的data是一个扁平的物体,你可以使用以下

const form = async (url, data) => {
  const encodedData = new URLSearchParams(data);
  return (await axiosApi.post(url, encodedData)).data;
};
Run Code Online (Sandbox Code Playgroud)

如果它更复杂,我建议使用像qs这样的库。

否则,等待 Axios 1.0,你显然可以使用它

axios.post(url, data, {
  headers: { "content-type": "application/x-www-form-urlencoded" }
});
Run Code Online (Sandbox Code Playgroud)