javascript React 和 Express 阻止了跨域请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50968152/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 09:21:14  来源:igfitidea点击:

Cross-Origin Request Blocked with React and Express

javascriptnode.jsreactjscors

提问by Alex Ironside

So I hit this error, when I was trying to send data to the back end using React. From what I learnt I need to allow the communication on the back-end and in the .htaccessfile. Here are some of the links I used:

所以当我尝试使用 React 将数据发送到后端时,我遇到了这个错误。据我所知,我需要允许在后端和.htaccess文件中进行通信。以下是我使用的一些链接:

No 'Access-Control-Allow-Origin' - Node / Apache Port Issue

没有 'Access-Control-Allow-Origin' - 节点/Apache 端口问题

How does Access-Control-Allow-Origin header work?

Access-Control-Allow-Origin 标头如何工作?

Both of them have code, but it didn't help.

他们都有代码,但没有帮助。

So far my Server-side code is this:

到目前为止,我的服务器端代码是这样的:

app.use(function (req, res, next) {
    // Website you wish to allow to connect
    // res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');

    res.setHeader('Access-Control-Allow-Origin', '*');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'POST');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});

This is my Client-side code:

这是我的客户端代码:

sendMail(e) {
    e.preventDefault();
    var name = document.getElementById('name').value;
    var contactReason = document.getElementById('contactReason').value;
    var email = document.getElementById('email').value;
    var additionalInfo = document.getElementById('additionalInfo').value;
    var body = {
        name: name,
        contactReason: contactReason,
        email: email,
        additionalInfo: additionalInfo,
    };
    console.log(JSON.stringify(body));
    fetch('http://localhost:4000/', {
        method: 'POST',
        body: body,
    }).then(r => console.log(r)).catch(e => console.log(e));
}

So what am I missing? I do not have an .htaccessfile, but I'm doing it all locally so I'm not sure if I can even use it.

那么我错过了什么?我没有.htaccess文件,但我都是在本地完成的,所以我不确定我是否可以使用它。

It looks to me like I'm allowing all I need, but I guess it's not enough.

在我看来,我允许我所需要的一切,但我想这还不够。

If you're going to mark as a duplicate, please at least make sure my issues are covered by the answer.

如果您要标记为重复,请至少确保我的问题包含在答案中。

回答by barro32

There's a node package called cors which makes it very easy.

有一个名为 cors 的节点包,这使它非常容易。

$npm install cors

$npm install cors

const cors = require('cors')

app.use(cors())

You don't need any config to allow all.

你不需要任何配置来允许所有。

See the Github repo for more info: https://github.com/expressjs/cors

有关更多信息,请参阅 Github 存储库:https: //github.com/expressjs/cors

回答by Karim

if you add this header

如果你添加这个标题

res.setHeader('Access-Control-Allow-Origin', '*');

you're using credential mode (means you're sending some authentication cookie from your app) and as for CORS specification you cannot use the wildcard * in this mode.

您正在使用凭证模式(意味着您正在从您的应用程序发送一些身份验证 cookie)并且对于 CORS 规范,您不能在此模式下使用通配符 *。

you should change your Access-Control-Allow-Originheader to match the specific host who generated the request

您应该更改Access-Control-Allow-Origin标头以匹配生成请求的特定主机

you can change this line:

你可以改变这一行:

res.header('Access-Control-Allow-Origin', '*');

to

res.header('Access-Control-Allow-Origin', 'the ip address');

but to be more generic, something like this should work:

但为了更通用,这样的事情应该有效:

res.setHeader('Access-Control-Allow-Origin', req.header('origin') 
|| req.header('x-forwarded-host') || req.header('referer') || req.header('host'));

in addition you have even to allow OPTIONS requests from the browser otherwise you will get a preflight request error.

此外,您甚至必须允许来自浏览器的 OPTIONS 请求,否则您将收到预检请求错误。

res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');

回答by Peter Wilson

you have to allow OPTIONSmethod as well

你也必须允许OPTIONS方法

res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');

the browser send it with any post request to other domain to check how it will communicate with this remote server.

浏览器将它与任何发布请求一起发送到其他域,以检查它将如何与该远程服务器通信。