【问题标题】:Axios post blocked by CORS. Using CLoudinary apiAxios 帖子被 CORS 阻止。使用 CLoudinary api
【发布时间】:2022-01-19 09:48:25
【问题描述】:

我正在尝试使用 axios 进行发布请求,以从我的前端 React 应用程序将图像上传到云端。我从下面的 axios 代码中收到此错误:

http://localhost:3000 已被 CORS 策略阻止:在预检响应中 Access-Control-Allow-Headers 不允许请求标头字段 x-access-token。

使用 axios,不起作用给我 cors 错误

await axios({
  method: "POST",
  url: "https://api.cloudinary.com/v1_1/******/image/upload/",
  data: {
    file: img,
    upload_preset: "*****",
    cloud_name: "****",
  },
})
  .then((res) => {
    console.log("response");
    console.log(res);
  })
  .catch((err) => console.log(err));

同时,当我使用相同的 api 请求使用 fetch 时,发布请求有效并且不会给我错误。有人知道为什么以及如何使用 axios 调用 api 吗?

  const data = new FormData();
        data.append("file", img);
        data.append("upload_preset", "*****");
        data.append("cloud_name", "*****");


  await fetch(
           "  https://api.cloudinary.com/v1_1/****/image/upload/",
           {
             method: "post",
             body: data,
           }
         )
           .then((resp) => resp.json())
           .then((data) => {
             setUrlArray((prevState) => [...prevState, data.url]);
           })
           .catch((err) => console.log(err));

额外信息:我的上传预设未签名。
在进行 axios api 调用后也从控制台得到了这个

{
error: {
message: "Upload preset must be specified when using unsigned upload"
}
}

【问题讨论】:

  • 我会检查您的开发工具中的标头,看看请求之间有什么不同。
  • Axios 使用 data 属性, body。见Request Config
  • 另一个区别是您的 Axios 请求发送的是 JSON,而您的 fetch() 发送的是 multipart/form-data。如果fetch() 适合你,为什么不直接使用它而不是 Axios?
  • 我找到了。在其中一个 redux thunk 文件中,他们有 axios.interceptors.request.use(async function (config) { const token = await localStorage.getItem("messenger-token"); config.headers["x-access-token"] = 令牌;返回配置;});
  • 多么奇怪的拦截器。 localStorage.getItem() 是同步的,那里不需要await

标签: reactjs axios cors fetch cloudinary


【解决方案1】:

要创建一个与您的工作 fetch() 等效的 Axios 请求,您需要

  1. 制作一个FormData 实例并将其设置为请求data,因此您的内容类型为multipart/form-data

  2. 确保您没有使用以前的 created Axios instance 和不需要的默认标头

  3. 如果在默认的 Axios 实例上设置了自定义标头,例如

    axios.defaults.headers.common["x-access-token"] = TOKEN
    

    您可能需要override / delete them in transformRequest

  4. 为避免在默认 Axios 实例上定义任何拦截器,请为未拦截的请求创建一个新的单独实例

import axios from "axios" // import the default instance

// create a new instance without interceptors. 
// you could also create this in its own module and import from there
const instance = axios.create()

const data = new FormData()
data.append("file", img);
data.append("upload_preset", "*****");
data.append("cloud_name", "*****");

const res = await instance.post(
  "https://api.cloudinary.com/v1_1/******/image/upload/", 
  data
)

理想情况下,如果您的应用要自定义请求,您应该始终使用 Axios 实例(或多个实例)以避免乱用默认值。

【讨论】:

  • 我已经试过了,但没用 :(
  • @dotaplayer 试了 what,没错。
  • 我尝试了你的代码和 cors 错误仍然在这里,但在链接中我没有收到错误:{ message: "Upload preset must be specified when using unsigned upload" } 现在我得到消息:错误{“对于未签名的上传,上传预设必须列入白名单”}
  • @dotaplayer 我已经更新了我的答案以展示如何避免默认拦截器
  • 非常感谢。终于成功了!!!
猜你喜欢
  • 2021-12-25
  • 2021-10-13
  • 2019-10-01
  • 2018-08-26
  • 2021-10-17
  • 2021-10-21
  • 2020-08-16
  • 2020-08-27
  • 2017-05-31
相关资源
最近更新 更多