【问题标题】:Getting express server to accept CORS request让快递服务器接受 CORS 请求
【发布时间】:2016-02-02 16:39:10
【问题描述】:

我的快速服务器在 http://localhost:3000 上运行(我称之为网络服务器) 我在 localhost:8100 上运行了另一个应用程序(我将其简称为“应用程序”)

当我的应用程序调用网络服务器时,我会收到消息:

“XMLHTTPReqeust 无法加载 http://localhost:3000/auth/facebook。对预检请求的响应未通过访问控制检查。通配符 '*' 不能在 'Access-Control-Allow-Origin' 中使用当凭据标志为真时。因此不允许访问源“http://localhost:81000””

此消息显示在浏览器控制台中。

我在节点网络服务器的中间件中设置了以下选项

res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT, POST,DELETE');

在阅读了几个stackoverfow问题后,我还添加了以下内容:

 res.header('Access-Control-Allow-Origin', 'http://localhost:8100');

但这并不能解决问题。

【问题讨论】:

  • 你还需要在Access-Control-Allow-Methods中允许OPTIONS方法

标签: node.js express cors


【解决方案1】:

您还必须考虑您的预检请求。我建议您在项目中添加“cors”npm 包,并使用以下配置启动它:

const cors = require('cors');

app.use(cors({
    credentials: true,
    preflightContinue: true,
    methods: ['GET', 'POST', 'PUT', 'PATCH , 'DELETE', 'OPTIONS'],
    origin: true
});

这将为使用所列方法的任何地址启用跨域请求。 origin 参数非常灵活,您可以分隔一组地址,所有地址或通过正则表达式,例如。这是包文档:

https://expressjs.com/en/resources/middleware/cors.html

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,并且跌跌撞撞了大约一个小时。解决方案实际上很简单——只需为 preflight operations 启用 CORS。

    app.options('*', cors()); // include before other routes
    

    【讨论】:

    • 结合 runtimeZero if-else 代码,这对我来说非常有效!更多详情here
    • 在其他路由之前需要包含 CORS 的处理这一事实有很大帮助。
    【解决方案3】:

    我以为我之前已经破解过这个,但是当我从 IIS 切换回 IIS Express 后,我又开始收到错误了!!

    再次开始使用 Google 并尝试了许多建议,包括上面的建议,但没有一个奏效,直到我发现这篇来自 Melvin's Web Stuff - Enable CORS IIS Express 的文章提出以下建议:

    将以下两行添加到<httpProtocol> 部分下的<customHeaders> 部分:

    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type" />
    

    到 applicationhost.config 位于:

    %HOMEPATH%\Documents\IISExpress\config
    

    最终的结果应该是这样的:

    <httpProtocol>
       <customHeaders>
          <clear />
             <add name="X-Powered-By" value="ASP.NET" />
             <add name="Access-Control-Allow-Origin" value="*" />
             <add name="Access-Control-Allow-Headers" value="Content-Type" />   
       </customHeaders>
       <redirectHeaders>
          <clear />
       </redirectHeaders>
    </httpProtocol>
    

    这对我来说效果很好,但请注意,在 IIS 中运行时我不需要上述内容。

    【讨论】:

      【解决方案4】:

      我使用cors并实现它,非常简单

      var cors=require('cors');

      app.use(cors({origin:true,credentials: true}));

      【讨论】:

      • 这对我有用。干净利落。你只需要“npm install cors”让它工作。
      • 这是接受所有来源的最佳解决方案,因为 origin:"*" 不起作用
      【解决方案5】:

      显然 cors 模块不起作用。

      使用上面给出的提示,我使用了以下代码:

        if (req.method === "OPTIONS") {
          res.header('Access-Control-Allow-Origin', req.headers.origin);
        } else {
          res.header('Access-Control-Allow-Origin', '*');
        }
      

      这成功了。

      【讨论】:

        【解决方案6】:

        您还需要在标题中允许OPTIONS 方法。

        我有这个用于 cors 的中间件:

        module.exports = function (req, res, next) {
            // CORS headers
            res.header("Access-Control-Allow-Origin", "YOUR_URL"); // restrict it to the required domain
            res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
            // Set custom headers for CORS
            res.header("Access-Control-Allow-Headers", "Content-type,Accept,X-Custom-Header");
        
            if (req.method === "OPTIONS") {
                return res.status(200).end();
            }
        
            return next();
        };
        

        PS。您得到的错误是由于跨域请求的工作原理。长话短说,浏览器可能首先使用方法OPTIONS 发送pre-flight 请求以获取允许的来源、标头和方法。因此,对于这个请求,您应该只返回 Access-Control-* 标头。如果pre-flight 正常,浏览器将继续原始请求。

        您可以找到更多信息here

        【讨论】:

        • 谢谢! if (req.method === "OPTIONS") 是我所缺少的
        【解决方案7】:

        我个人更喜欢cors 模块。代码很简单:

        var whitelist = [
            'http://0.0.0.0:3000',
        ];
        var corsOptions = {
            origin: function(origin, callback){
                var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
                callback(null, originIsWhitelisted);
            },
            credentials: true
        };
        app.use(cors(corsOptions));
        

        【讨论】:

        • 我建议按照 Thomas 的建议使用 cors 模块,而不是处理标题内容。它易于设置和使用。解决一般问题只需 30 秒。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多