Axios不遵守内容类型标头

wsewodh2  于 2023-01-30  发布在  iOS
关注(0)|答案(1)|浏览(135)

这是我的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)
}

如您所见,对于postget实用程序方法,我使用了一个设置默认值的请求拦截器,因此我使用了Content-Type: application/json
但是,对于form,我将Content-Type标头重写为一个表单。
我读了一些其他的问题,包括:
Axios not passing Content-Type header
Axios Header's Content-Type not set for safari
但我的服务器允许在CORS请求中发送Content-Type

Access-Control-Allow-Headers: authorization,content-type,x-client
Access-Control-Allow-Methods: POST
Access-Control-Allow-Origin: *

但是当我使用form方法时,我看到Content-Type没有设置为application/json,而不是application/x-www-form-urlencoded
我做错了什么?

w6lpcovy

w6lpcovy1#

默认情况下,Axios具有出色的请求主体处理。

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

那么,为什么对带有定制content-type头文件的Stack Overflow会有无尽的疑问呢?我甚至认为,除非您的API使用正确的content negotiation,否则您也不需要对Accept头文件进行干预。
我认为在您的情况下不需要拦截器,只需在示例上设置请求头默认值即可

axiosApi.defaults.headers.common["X-Client"] = "React";
// and if your API actually uses content negotiation...
// axiosApi.defaults.headers.common.Accept = "application/json";

至于你的 url-encoded 请求,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;
};

如果比较复杂,我建议使用qs这样的库。
否则,请等待Axios 1.0,在那里您可以 * 显然 * 使用此功能

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

相关问题