【问题标题】:No 'Access-Control-Allow-Origin' - Node / Apache Port Issue没有“Access-Control-Allow-Origin” - 节点/Apache 端口问题
【发布时间】:2013-08-21 01:10:17
【问题描述】:

我已经使用 Node/Express 创建了一个小型 API,并尝试使用 Angularjs 提取数据,但是由于我的 html 页面在 localhost:8888 上的 apache 下运行,并且节点 API 在端口 3000 上侦听,因此我得到了 No 'Access -控制-允许-来源'。我尝试使用 node-http-proxy 和 Vhosts Apache,但没有太多成功,请参阅下面的完整错误和代码。

XMLHttpRequest 无法加载 localhost:3000。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问 Origin 'localhost:8888'。"

// Api Using Node/Express    
var express = require('express');
var app = express();
var contractors = [
    {   
     "id": "1", 
        "name": "Joe Blogg",
        "Weeks": 3,
        "Photo": "1.png"
    }
];

app.use(express.bodyParser());

app.get('/', function(req, res) {
  res.json(contractors);
});
app.listen(process.env.PORT || 3000);
console.log('Server is running on Port 3000')

角度代码

angular.module('contractorsApp', [])
.controller('ContractorsCtrl', function($scope, $http,$routeParams) {

   $http.get('localhost:3000').then(function(response) {
       var data = response.data;
       $scope.contractors = data;
   })

HTML

<body ng-app="contractorsApp">
    <div ng-controller="ContractorsCtrl"> 
        <ul>
            <li ng-repeat="person in contractors">{{person.name}}</li>
        </ul>
    </div>
</body>

【问题讨论】:

    标签: node.js angularjs rest express cors


    【解决方案1】:

    尝试将以下中间件添加到您的 NodeJS/Express 应用程序中(为了您的方便,我添加了一些 cmets):

    // Add headers before the routes are defined
    app.use(function (req, res, next) {
    
        // Website you wish to allow to connect
        res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');
    
        // Request methods you wish to allow
        res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    
        // 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();
    });
    

    希望有帮助!

    【讨论】:

    • 你能帮忙具体说明它的去向吗?我的服务器中有以下代码。在这之后就可以了吗? var app = require('express')() , server = require('http').createServer(app) , io = require('socket.io').listen(server) , request = require("request") , url = 需要("url"); server.listen(6969); // 它到这里了吗?换行了吗?
    • @jvandemo 我必须将 app.get('/', function(req, res) 更改为 ...function(req, res, next) 吗?
    • 你现在是我最喜欢的人。谢谢你。我们可以添加一个注释,这个代码必须在为像我这样的菜鸟定义路由之前发生吗?
    • 如何在使用请求模块时进行这项工作?
    • 它在我的情况下不起作用。仍然收到此错误:“对预检请求的响应未通过访问控制检查:请求的资源上不存在 'Access-Control-Allow-Origin' 标头。因此不允许访问 Origin 'abc.xyz.net:212'。响应HTTP 状态码为 500。”
    【解决方案2】:

    接受的答案很好,如果你喜欢更短的东西,你可以使用一个名为 cors 的插件,可用于 Express.js

    对于这种特殊情况,使用起来很简单:

    var cors = require('cors');
    
    // use it before all route definitions
    app.use(cors({origin: 'http://localhost:8888'}));
    

    【讨论】:

    • 我必须使用{origin: 'null'} 才能工作...显然,我的浏览器发送null 作为来源?
    • 为什么要重新发明轮子。与代码 sn-p 相比,我始终支持打包解决方案
    • 可爱的小库,它很好地处理了我想要来自不同来源的不同方法的用例......并且为下一个查看它的人减少了代码疲劳。
    • 谢谢,app.use(cors({origin: '*'})); 按照enable-cors 为我工作。
    • 我建议查看npm cors page 以更好地利用它。这对我来说很清楚 =)。
    【解决方案3】:

    另一种方法,只需将标题添加到您的路线:

    router.get('/', function(req, res) {
        res.setHeader('Access-Control-Allow-Origin', '*');
        res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); // If needed
        res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); // If needed
        res.setHeader('Access-Control-Allow-Credentials', true); // If needed
    
        res.send('cors problem fixed:)');
    });
    

    【讨论】:

    • )的笑脸把我弄糊涂了
    【解决方案4】:

    top answer 对我来说效果很好,只是我需要将多个域列入白名单。

    此外,最佳答案还受到以下事实的影响:OPTIONS 请求不是由中间件处理并且您不会自动获取它。

    我在 Express 配置中将列入白名单的域存储为 allowed_origins,并根据 origin 标头放置正确的域,因为 Access-Control-Allow-Origin 不允许指定多个域。

    这就是我最终得到的结果:

    var _ = require('underscore');
    
    function allowCrossDomain(req, res, next) {
      res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    
      var origin = req.headers.origin;
      if (_.contains(app.get('allowed_origins'), origin)) {
        res.setHeader('Access-Control-Allow-Origin', origin);
      }
    
      if (req.method === 'OPTIONS') {
        res.send(200);
      } else {
        next();
      }
    }
    
    app.configure(function () {
      app.use(express.logger());
      app.use(express.bodyParser());
      app.use(allowCrossDomain);
    });
    

    【讨论】:

    • 这和'if (app.get('allowed origins').indexOf(origin)!==-1)?'一样吗?
    【解决方案5】:

    答案代码只允许本地主机:8888。此代码不能部署到生产,或不同的服务器和端口名称。

    要使其适用于所有来源,请改用它:

    // Add headers
    app.use(function (req, res, next) {
    
        // Website you wish to allow to connect
        res.setHeader('Access-Control-Allow-Origin', '*');
    
        // Request methods you wish to allow
        res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    
        // 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();
    });
    

    【讨论】:

    • 这对我不起作用! “ * 不是有效的来源”。似乎 * 字符未被识别为通配符。
    • 它对我有用。即使用通配符“*”。适用于 chrome 和 safari。
    • 谢谢 ;) 工作正常
    【解决方案6】:

    在你的项目中安装 cors 依赖:

    npm i --save cors
    

    将以下内容添加到您的服务器配置文件中:

    var cors = require('cors');
    app.use(cors());
    

    它适用于我的 2.8.4 cors 版本。

    【讨论】:

    • "cors": "^2.8.5", "express": "^4.16.3", 与@monikaja 建议的行一起工作得很好。谢谢!
    • 这样做是为了让所有来源/域都能访问应用程序,这是您通常不想做的事情。而是只指定允许的域。
    • 经过 4-5 小时的搜索,这是唯一真正适合我的解决方案。谢谢
    【解决方案7】:

    您好,当前端和后端在不同的端口上运行时会发生这种情况。由于缺少 CORS 标头,浏览器会阻止来自后端的响应。解决方案是在后端请求中添加 CORS 标头。最简单的方法是使用 cors npm 包。

    var express = require('express')
    var cors = require('cors')
    var app = express()
    app.use(cors())
    

    这将在您的所有请求中启用 CORS 标头。更多信息可以参考 cors 文档

    https://www.npmjs.com/package/cors

    【讨论】:

      【解决方案8】:

      这对我有用。

      app.get('/', function (req, res) {
      
          res.header("Access-Control-Allow-Origin", "*");
          res.send('hello world')
      })
      

      您可以更改 * 以满足您的需要。希望这能有所帮助。

      【讨论】:

        【解决方案9】:

        所有其他答案都不适合我。 (包括cors包,或者通过中间件设置headers)

        对于 socket.io 3^ 这在没有任何额外包的情况下工作。

        const express = require('express');
        const app = express();
        
        const server = require('http').createServer(app);
        const io = require('socket.io')(server, {
            cors: {
                origin: "*",
                methods: ["GET", "POST"]
            }
        });
        

        【讨论】:

        • 这是有史以来最好的回复!与socketio一起工作。谢谢
        【解决方案10】:
        app.all('*', function(req, res,next) {
            /**
             * Response settings
             * @type {Object}
             */
            var responseSettings = {
                "AccessControlAllowOrigin": req.headers.origin,
                "AccessControlAllowHeaders": "Content-Type,X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5,  Date, X-Api-Version, X-File-Name",
                "AccessControlAllowMethods": "POST, GET, PUT, DELETE, OPTIONS",
                "AccessControlAllowCredentials": true
            };
        
            /**
             * Headers
             */
            res.header("Access-Control-Allow-Credentials", responseSettings.AccessControlAllowCredentials);
            res.header("Access-Control-Allow-Origin",  responseSettings.AccessControlAllowOrigin);
            res.header("Access-Control-Allow-Headers", (req.headers['access-control-request-headers']) ? req.headers['access-control-request-headers'] : "x-requested-with");
            res.header("Access-Control-Allow-Methods", (req.headers['access-control-request-method']) ? req.headers['access-control-request-method'] : responseSettings.AccessControlAllowMethods);
        
            if ('OPTIONS' == req.method) {
                res.send(200);
            }
            else {
                next();
            }
        
        
        });
        

        【讨论】:

        【解决方案11】:

        在 NODEJ Restful api 的 app.js 中添加以下代码,以避免 Angular 6 或任何其他框架中的“Access-Control-Allow-Origin”错误

        var express = require('express');
        var app = express();
        
        var cors = require('cors');
        var bodyParser = require('body-parser');
        
        //enables cors
        app.use(cors({
          'allowedHeaders': ['sessionId', 'Content-Type'],
          'exposedHeaders': ['sessionId'],
          'origin': '*',
          'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
          'preflightContinue': false
        }));
        

        【讨论】:

          【解决方案12】:

          你可以使用“$http.jsonp”

          以下是用于本地测试的 chrome 解决方法

          您需要使用以下命令打开您的 chrome。 (按窗口+R)

          Chrome.exe --allow-file-access-from-files
          

          注意:您的 chrome 不得打开。运行此命令时,chrome 会自动打开。

          如果您在命令提示符下输入此命令,请选择您的 chrome 安装目录,然后使用此命令。

          下面是在 MAC 中使用“--allow-file-access-from-files”打开 chrome 的脚本代码

          set chromePath to POSIX path of "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" 
          set switch to " --allow-file-access-from-files"
          do shell script (quoted form of chromePath) & switch & " > /dev/null 2>&1 &"
          

          第二个选项

          您可以使用 open(1) 添加标志: open -a 'Google Chrome' --args --allow-file-access-from-files

          【讨论】:

          • 在 MAC 上怎么样?? Chrome.exe --allow-file-access-from-files
          • /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files 设法打开 chrome 但消息仍显示“XMLHttpRequest 无法加载 @ 987654322@. Origin localhost:8888 不被 Access-Control-Allow-Origin 所允许。"
          • +1 我可以确认这适用于使用“打开”的 Mac 选项。我的情况有点不同,因为我只是在测试一个完全下载的访问一些本地 JSON 文件的站点。
          【解决方案13】:

          你可以使用 cors 包来处理它。

          var cors = require('cors')
          var app = express()
          
          app.use(cors())
          

          用于设置具体原点

          app.use(cors({origin: 'http://localhost:8080'}));
          

          know more

          【讨论】:

            【解决方案14】:

            /**
             * Allow cross origin to access our /public directory from any site.
             * Make sure this header option is defined before defining of static path to /public directory
             */
            expressApp.use('/public',function(req, res, next) {
                res.setHeader("Access-Control-Allow-Origin", "*");
                // Request headers you wish to allow
                res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                // Set to true if you need the website to include cookies in the requests sent
                res.setHeader('Access-Control-Allow-Credentials', true);
                // Pass to next layer of middleware
                next();
            });
            
            
            /**
             * Server is about set up. Now track for css/js/images request from the 
             * browser directly. Send static resources from "./public" directory. 
             */
            expressApp.use('/public', express.static(path.join(__dirname, 'public')));
            If you want to set Access-Control-Allow-Origin to a specific static directory you can set the following.

            【讨论】:

              【解决方案15】:

              除了所有列出的答案,我有同样的错误

              我可以同时访问前端和后端,我已经添加了 cors 模块 app.use(cors()); 不过,我仍然在为这个错误而苦苦挣扎。

              经过一番调试,我发现了问题所在。当我上传大小超过 1 MB 的媒体时,Nginx 服务器

              引发了错误
              <html>
              
              <head>
                  <title>413 Request Entity Too Large</title>
              </head>
              
              <body>
                  <center>
                      <h1>413 Request Entity Too Large</h1>
                  </center>
                  <hr>
                  <center>nginx/1.18.0</center>
              </body>
              
              </html>
              

              但是在前端的控制台中,我发现了错误

              Access to XMLHttpRequest at 'https://api.yourbackend.com' from origin 'https://web.yourfromntend.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
              

              所以这里很混乱。但是这个错误的路由原因是来自 nginx 配置。这只是因为指令client_max_body_size 的值已默认设置为0。它决定了允许的 HTTP 请求大小可以是client_max_body_size。该指令可能已经在位于/etc/nginx/nginx.confnginx.conf 文件中定义。现在您需要在httpserver 添加/编辑指令client_max_body_size 的值。

              server {
                  client_max_body_size 100M;
                  ...
              }
              

              设置所需值后,保存更改并重新加载 Nginxservice nginx reload

              经过这些更改,它运行良好

              参考https://www.keycdn.com/support/413-request-entity-too-large#:~:text=%23,processed%20by%20the%20web%20server.&text=An%20example%20request%2C%20that%20may,e.g.%20a%20large%20media%20file)。

              【讨论】:

                猜你喜欢
                • 2021-05-29
                • 1970-01-01
                • 2015-12-28
                • 2019-02-06
                • 2013-09-28
                • 2016-04-22
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多