[英]Nodejs Express CORS issue with 'Access-Control-Allow-Origin'
我正在尝试使用 Angular 1、Nodejs 和 Express 创建一个单页应用程序。 我正在使用 Angular 的 $http post 功能来发布请求,我将请求中的标头值传递给 API 端点。
我在 Chrome 中遇到错误消息:
XMLHttpRequest cannot load
http://localhost:7878/EIAMIDSupportREST/EIAMIDSupport/updateEIAMID. The
value of the 'Access-Control-Allow-Origin' header in the response must not
be the wildcard '*' when the request's credentials mode is 'include'. Origin
'http://localhost:3000' is therefore not allowed access. The credentials
mode of requests initiated by the XMLHttpRequest is controlled by the
withCredentials attribute.
使用此请求正文:
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,PUT,POST,PATCH,DELETE
Access-Control-Allow-Headers: Content-Type
Allow: POST
Content-Type: text/html; charset=utf-8
Content-Length: 4
Date: Tue, 23 May 2017 23:32:15 GMT
Connection: keep-alive
为了解决 CORS 问题,我 npm 安装了cors
库。
在我的 app.js 中,我添加了以下几行:
var cors = require('cors');
var app = express();
app.use(cors());
这是我的完整 app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var users = require('./routes/users');
var cons = require('consolidate');
//enable CORS
var cors = require('cors');
var app = express();
app.use(cors({ origin: 'http://localhost:3000' , credentials : true, methods: 'GET,PUT,POST,OPTIONS', allowedHeaders: 'Content-Type,Authorization' }));
// view engine setup
app.engine('html', cons.swig)
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
这是我的 index.html 页面
<html>
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module("app", []);
app.controller("HttpGetController", function ($scope, $http) {
$scope.SendData = function () {
var req = {
method: 'POST',
url: 'http://localhost:7878/EIAMIDSupportREST/EIAMIDSupport/updateEIAMID',
withCredentials: true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic user:password'
}
}
$http(req)
.then(function(data, status, header, config)
{
$scope.PostDataResponse = data,
console.log($scope.PostDataResponse);
})
.catch(function(data, status, header, config)
{
$scope.PostDataResponse = data,
console.log($scope.PostDataResponse);
});
};
});
</script>
</head>
<body>
<div ng-app="app">
<div ng-controller="HttpGetController">
<button ng-click="SendData()" >Link Accounts</button>
<hr />AND THE RESPONSE IS:{{ PostDataResponse }}
</div>
</div>
</body>
</html>
但是,它仍然不起作用。
任何人都可以告诉我如何以及在哪里更新我的代码以解决“访问控制允许来源”通配符问题?
虽然@muratgozel 的答案部分正确,但让我更深入地了解 CORS 以及导致该问题的原因。 当您的浏览器发送跨域响应时,它会在标头中给出它的 Origin 。 服务器响应还提供了一个名为 Access-Control-Allow-Origin 的标头。 当您在 express 应用程序中使用实例化 'cors' 模块时,Access-Control-Allow-Origin 标头设置为 '*' 通配符,这基本上意味着该服务器资源(express 应用程序的)是公开的并且可以可以从任何地方的任何代码访问,但是此通配符的限制是请求中不允许某些请求标头,例如 Authorization。 您来自 index.html 页面的请求有一组 headers 。 您应该查看标题,或者您可以简单地按照@muratgozel 所说的进行操作并实例化具有特定来源的 cors 除了将凭据选项设置为 true
app.use(cors({ origin: 'http://example.com' , credentials : true}));
还有一个选项可以将origin
设置为true
以反映请求来源,如req.header('Origin')
所定义。
app.use(cors({ origin: true, credentials: true }));
您的cors
包有一个 origin 选项,可以更改“Access-Control-Allow-Origin”标头。
指定启动 cors() 函数的 origin 选项:
app.use(cors({ origin: 'http://example.com' }));
在cors 包 npm 页面上还有更多详细信息
以防万一有人想使用基于纯 javascript 的解决方案,这里是在我的 Google Chrome (80)、Mozilla Firefox (72) 和 Microsoft Edge 浏览器上运行的代码。
我正在使用 NodeJS (12) 开发一个小型分布式 REST API。 如果这组服务部署在同一台机器上,则使用不同的端口号来分隔它们。
另一方面,几个前端应用程序应该同时与许多服务交互。 所以,我在集成阶段开始收到这个 CORS 错误。 我为 javascript 找到的解决方案如下。
在这里,诀窍很简单。 您只想在每个响应中添加以下行。
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4000');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Accept');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
注意: res 是 HTTP 响应对象。
在这种情况下,请求像往常一样编码。 我们唯一需要知道的是,在我们要发送的每个请求之前,浏览器将首先使用 HTTP“OPTIONS”方法发送一个预检请求。 这个预检请求将根据其内部 CORS 策略告诉浏览器是否会收到您的原始请求的答案。
在这个例子中,我使用 POST 方法只发送了一个 JSON 对象:
var xhr = new XMLHttpRequest();
xhr.open(method, requestUrl);
xhr.setRequestHeader('Content-type', 'text/plain');
为了相应地处理 OPTIONS 请求,您必须按如下方式检查服务器端:
if (req.method.toLowerCase() == 'options')
res.writeHead(200);
就是这样,没有额外的并发症。
当您需要通过标头发送令牌时,您必须将“令牌”添加到“选项”响应中,如下所示:
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, token');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.