Axios出现CORS问题

138

我在package.json中添加了代理并取得了良好的效果,但在运行npm run build后,跨域问题又再次出现了。有人知道如何在React中处理npm run build后的CORS问题吗?

我尝试使用各种方法在axios请求中添加头信息,但是未能成功添加'Access-Control-Allow-Origin':'*'。我的代码如下:

package.json

  "proxy": {
      "*":{ "target" : "http://myurl"}
   } 

GetData.js

  axios.defaults.baseURL = 'http://myurl';
  axios.defaults.headers.post['Content-Type'] ='application/json;charset=utf-8';
  axios.defaults.headers.post['Access-Control-Allow-Origin'] = '*';
  axios.get(serviceUrl, onSuccess, onFailure)
  .then(resp => { 
        let result = resp.data;
        onSuccess(result);
  })
  .catch(error => {
        if(onFailure) {
            return onFailure(error);
        }
  })
 }

注意:虽然它已在服务器端启用,但仍未起作用。目前,我无法从服务器端更改代码,我的工作仅限于客户端。


1
这个回答解决了你的问题吗?当尝试从REST API获取数据时,“请求的资源上不存在'Access-Control-Allow-Origin'标头”是什么意思? - Nils Schwebel
12个回答

126

您的服务器应该启用跨域请求,而不是客户端。为了做到这一点,您可以查看这个很好的页面,其中有多个平台的实现和配置。


22
已经在服务器端启用,但仍无法正常工作。目前,我无法从服务器端更改代码,我的工作仅限于客户端。 - Kiran
4
也许服务器端配置不正确。检查Google Chrome的网络选项卡,应该会有两个请求。第一个请求是preflight请求(只是为了检查CORS标头)。也许服务器没有正确地回答这个preflight请求。 - Murilo Cruz
4
没错,你是对的,需要从服务器端解决。 - Kiran
对于asp.net Core 2 webapi,您可以在微软官方文档中按照说明进行操作。 - Stark
3
如果您无法控制服务器端,仍需要以其他方式解决这个问题。 - Greggory Wiley
访问控制允许来源不应该是*,而应该是接受来源的值。建议的最佳实践是将来源与允许列表进行比较,然后在响应中返回接受的域作为标头的值。这是MDN所说的。 - lukeocodes

33

只是记录一下我的解决方案,希望能够帮到通过谷歌搜索到达这里的人。我通过在 axios 调用中将 withCredentials 设置为 false 来解决跨域资源共享问题(在浏览器中从我的 UI 调用外部 API 时出现的问题):

axios({
    method: 'get',
    url: `https://api.someurl.com/subject/v2/resource/somevalue`,
    withCredentials: false,
    params: {
      access_token: SECRET_TOKEN,
    },
  });

在这种情况下,外部 API 的端点安全性基于 access_token


根据文档的说明,withCredentials默认情况下应该设置为false,但很高兴知道它可能会起作用。 - undefined
这解决了我在向AWS API Gateway端点发出请求时遇到的CORS问题。 - undefined

18

我遇到了相同的问题。当我更改内容类型时,问题得以解决。我不确定这个解决方案是否适用于你,但或许可以试一试。如果您不介意内容类型,它对我很有效。

axios.defaults.headers.post['Content-Type'] ='application/x-www-form-urlencoded';

这是有效的,因为您更改为简单请求,在这种情况下,来自服务器的响应只需要包括头部Access-Control-Allow-Origin。 - clonq
事实上,在那之后,我意识到我的Access-Control-Allow-Headers存在一些错误,需要正确地进行整理。我认为关键点就在于此。 - soztrk
我正在从React前端向PHP后端发起POST请求,但一直收到CORS错误,这很奇怪,因为我已经在服务器上设置了所有的CORS内容。谢谢,伙计!我欠你一杯咖啡。 - nixx

18

可能对某人有帮助:

我正在从一个 react 应用程序向一个 golang 服务器发送数据。

一旦我更改了这个,w.Header().Set("Access-Control-Allow-Origin", "*"),错误就被解决了。

React表单提交函数:

async handleSubmit(e) {
    e.preventDefault();
    
    const headers = {
        'Content-Type': 'text/plain'
    };

    await axios.post(
        'http://localhost:3001/login',
        {
            user_name: this.state.user_name,
            password: this.state.password,
        },
        {headers}
        ).then(response => {
            console.log("Success ========>", response);
        })
        .catch(error => {
            console.log("Error ========>", error);
        }
    )
}

Go服务器获得路由器功能

func main()  {
    router := mux.NewRouter()

    router.HandleFunc("/login", Login.Login).Methods("POST")

    log.Fatal(http.ListenAndServe(":3001", router))
}

Login.go,

Login.go,

func Login(w http.ResponseWriter, r *http.Request)  {

    var user = Models.User{}
    data, err := ioutil.ReadAll(r.Body)

    if err == nil {
        err := json.Unmarshal(data, &user)
        if err == nil {
            user = Postgres.GetUser(user.UserName, user.Password)
            w.Header().Set("Access-Control-Allow-Origin", "*")
            json.NewEncoder(w).Encode(user)
        }
    }
}

1
当我将"Access-Control-Allow-Origin"添加到我的标头中时,它对我也起作用了!我知道我晚了2年,但这怎么能解决CORS问题呢?非常感谢! - Francis Magnusson

6

这是由于跨域限制原始来源策略导致的。浏览器发送预检请求以了解API服务器想要共享资源的对象。因此,您必须在API服务器中设置起源并发送一些状态。之后,浏览器才允许向API服务器发送请求。

这里是代码。我正在本地主机端口8000运行前端,而API服务器正在6000端口上运行。

const cors = require("cors");

app.options("*", cors({ origin: 'http://localhost:8000', optionsSuccessStatus: 200 }));

app.use(cors({ origin: "http://localhost:8000", optionsSuccessStatus: 200 }));

我已将前端URL设置为起点。如果您将其设置为true,则仅允许端口8000访问资源,而运行在端口8000上的前端无法访问此资源。在api服务器中的路由之前使用此中间件。


6

我在Vue.js项目中遇到了同样的CORS错误。您可以通过构建代理服务器或另一种方法来解决这个问题,即禁用浏览器(例如,CHROME)的安全设置以访问跨源API(这是临时解决方案,不是解决问题的最佳方法)。这两种解决方案都对我起作用。后一种解决方案不需要构建任何模拟服务器或代理服务器。这两种解决方案都可以在前端解决。

您可以通过在终端上键入以下命令来禁用Chrome安全设置以访问来源之外的API:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir="/tmp/chrome_dev_session" --disable-web-security

在终端上运行上述命令后,将打开一个禁用安全设置的新Chrome窗口。现在,再次运行您的程序(npm run serve / npm run dev),这次您将不会收到任何CORS错误,并且可以使用axios进行GET请求。
希望这能帮助您!

1
这实际上帮助我解决了我的问题。谢谢。 - vandu
是的,从某种程度上说,这是“不好”的做法,但它足以在编码时从本地开发框中测试。然后,您可以部署到实际的测试/暂存环境,在那里您拥有适当的名称和证书以及CORS标头,可以进行适当/更完整的集成测试,模拟生产环境。非常感谢您帮我解决了困境。 - Daniele Muscetta

4
这对我有用:
在 JavaScript 中:
Axios({
            method: 'post',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            url: 'https://localhost:44346/Order/Order/GiveOrder',
            data: order
          }).then(function (response) {
            console.log(response.data);
          });

并且在后端(.net core)中:

在启动时:

 #region Allow-Orgin
            services.AddCors(c =>
            {
                c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
            });
            #endregion

在控制器中的动作之前

[EnableCors("AllowOrigin")]

16
停止允许所有来源。 - Yoker
2
这对于本地测试来说还可以,但在部署时应非常小心。 - Shrivallabh

3

当我使用Axios时,遇到了相同的问题,然后我看到了这个帖子。回复中没有提到的是,使用no-cors模式的fetch可以解决你的问题。

为什么?

显然,Axios在底层使用XMLHttpRequest而不是Request,因此Axios失败,因为CORS仍然被强制执行,而no-cors模式不受支持。

请查看此帖子以获取更多信息。


1
CORS问题仅在浏览器中出现。它发生是因为服务器不允许来自其他服务器的请求,例如,如果我从http://localhost:3000发送请求到任何API(http://example.com/users)以从这里获取用户数据。如果服务器无法识别您的本地主机,则会遇到问题。@CrossOrigin(Origin = "*") //如果使用此注释,将允许来自任何服务器的任何请求,您将不会遇到CORS问题。现在,如果您正在使用axios在react中向另一个不在您控制范围内的服务器发送请求,则克服该问题的方法是使用http-proxy-middleware。npm i http-proxy-middleware //安装此依赖项 axios. {method:'post',url:'/endpoint',headers:{'Content-Type':'application / json'},proxy:createProxyMiddleware({target:'https://www.api.com',changeOrigin:true}),data:data};现在以这种方式发送代理请求www.api.com/endpoint,因此您将不会收到cors问题。

请在您的package.json中添加以下内容:

"proxy": "https://www.api.com"


(原文已翻译,保留HTML标记)

1
如果您正在使用自己的服务器,只需在服务器端允许CORS即可。 如果您正在使用其他API(例如OneSignal),则需要创建一个服务器来请求API端点。大多数API提供者会阻止客户端对其API的请求。 - Rashid Iqbal

-3
请尝试这个...它对我有效。
axios.get(`http://localhost:4000/api`,{ crossdomain: true }).then((result)=>{
        console.log("result",result);
      }).catch((error)=>{
        console.log("Error",error);
      });

7
建议的属性'crossdomain'未被接受,也不起作用。我确认了这一点,针对axios 0.21.1版本(目前最新版本)。 - David Zwart
1
Pankaj Solution为我工作。 - Wayne Tun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接