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

use*_*103 230 rest node.js cors express angularjs

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

"XMLHttpRequest无法加载localhost:3000.请求的资源上没有'Access-Control-Allow-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')
Run Code Online (Sandbox Code Playgroud)

jva*_*emo 575

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

// Add headers
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();
});
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!

  • 你现在是我最喜欢的人.谢谢.我们可以添加一个注释,在为像我这样的新手定义路由之前,这个代码必须发生吗? (8认同)
  • 在我的情况下它不起作用。仍然收到此错误:“对预检请求的响应未通过访问控制检查:请求的资源上不存在‘Access-Control-Allow-Origin’标头。来源‘http://abc.xyz.net:212’因此不允许访问。响应的 HTTP 状态代码为 500。” (3认同)
  • 你能帮忙详细说明一下去哪里吗?我的服务器中有以下代码.它之后是否正确?var app = require('express')(),server = require('http').createServer(app),io = require('socket.io').listen(server),request = require("request") ,url = require("url"); server.listen(6969); //它去了吗?在新线上? (2认同)

Fab*_*ani 88

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

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

var cors = require('cors');

// use it before all route definitions
app.use(cors({origin: 'http://localhost:8888'}));
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,`app.use(cors({origin:'*'}));`按照[enable-cors](https://enable-cors.org/server_expressjs.html)为我工作. (5认同)
  • 我不得不使用`{origin:'null'}`来工作......显然,我的浏览器发送`null`作为原点? (3认同)
  • 为什么重新发明轮子.与代码片段相比,我总是寻求打包的解决方案 (2认同)
  • 我建议查看 [npm cors 页面](https://www.npmjs.com/package/cors) 以更好地利用它。这对我来说很清楚=)。 (2认同)

Asa*_*nel 29

另一种方法是简单地将标题添加到您的路线:

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:)');
});
Run Code Online (Sandbox Code Playgroud)

  • `)笑脸让我很困惑 (5认同)

Dan*_*mov 15

顶部的答案对我来说工作得很好,但我需要添加到白名单不止一个域.

此外,最佳答案OPTIONS是因为中间件不处理请求而您没有自动获取请求.

我按照allowed_originsExpress配置存储列入白名单的域,并根据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);
});
Run Code Online (Sandbox Code Playgroud)

  • 这是否与“if (app.get('allowed origins').indexOf(origin)!==-1) 相同?”? (2认同)

Kar*_*mar 14

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

var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
Run Code Online (Sandbox Code Playgroud)

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

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


Vic*_*nak 13

答案代码仅允许localhost: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();
});
Run Code Online (Sandbox Code Playgroud)

  • 这对我不起作用!"*不是有效的来源".似乎*字符不被识别为通配符. (2认同)

小智 8

在项目中安装cors依赖项:

npm i --save cors
Run Code Online (Sandbox Code Playgroud)

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

var cors = require('cors');
app.use(cors());
Run Code Online (Sandbox Code Playgroud)

它适用于我的2.8.4 cors版本.


Wik*_*iki 5

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();
    }


});
Run Code Online (Sandbox Code Playgroud)


dmx*_*dmx 5

这对我有用。

app.get('/', function (req, res) {

    res.header("Access-Control-Allow-Origin", "*");
    res.send('hello world')
})
Run Code Online (Sandbox Code Playgroud)

您可以更改*以适合您的需求。希望这会有所帮助。


Gil*_*ong 5

所有其他答案对我都不起作用。(包括 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"]
    }
});
Run Code Online (Sandbox Code Playgroud)