我使用Node / Express创建了一个小API,并尝试使用Angularjs来提取数据,但是当我的html页面在localhost:8888上的apache下运行,而节点API在端口3000上侦听时,我得到了No'访问权限 - 控制允许来源。我尝试使用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')
// Angular code
angular.module('contractorsApp', [])
.controller('ContractorsCtrl', function($scope, $http,$routeParams) {
$http.get('localhost:3000').success(function(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>
答案 0 :(得分:545)
尝试将以下中间件添加到您的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();
});
希望有所帮助!
答案 1 :(得分:81)
接受的答案很好,如果您喜欢更短的内容,可以使用名为 cors 的插件,可用于Express.js
对于这种特殊情况,使用起来很简单:
var cors = require('cors');
// use it before all route definitions
app.use(cors({origin: 'http://localhost:8888'}));
答案 2 :(得分:27)
另一种方法是简单地将标题添加到您的路线中:
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:)');
});
答案 3 :(得分:14)
top answer对我来说很好,除了我需要将多个域列入白名单。
此外,最佳答案还有一个事实,即OPTIONS
请求不是由中间件处理的,而且您无法自动获取。
我将列入白名单的域名allowed_origins
存储在Express配置中,并根据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);
});
答案 4 :(得分:12)
答案代码仅允许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();
});
答案 5 :(得分:6)
在您的项目中安装cors依赖项:
npm i --save cors
将以下内容添加到服务器配置文件中:
var cors = require('cors');
app.use(cors());
它适用于我的2.8.4 cors版本。
答案 6 :(得分: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"]
}
});
答案 7 :(得分:4)
这对我有用。
app.get('/', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.send('hello world')
})
您可以更改*以适合您的需求。希望这会有所帮助。
答案 8 :(得分:3)
嗨,这发生在前端和后端在不同端口上运行时。由于缺少CORS标头,浏览器阻止了来自后端的响应。解决方案是在后端请求中添加CORS标头。最简单的方法是使用cors npm软件包。
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
这将在您的所有请求中启用CORS标头。有关更多信息,请参阅cors文档
答案 9 :(得分:2)
//Add following code in app.js of NODEJ Restful api to avoid "Access-Control-Allow-Origin" error in angular 6 or any other framework
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
}));
答案 10 :(得分:1)
您可以使用“$ http.jsonp”
OR
以下是针对本地测试的chrome的解决方法
您需要使用以下命令打开chrome。 (按窗口+ R)
Chrome.exe --allow-file-access-from-files
注意:您的镶边不得打开。运行此命令时,chrome将自动打开。
如果在命令提示符下输入此命令,请选择chrome安装目录,然后使用此命令。
使用“--allow-file-access-from-files”
在MAC中打开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
答案 11 :(得分:1)
除了所有列出的答案,我有相同的错误
我既可以访问前端也可以访问后端,我已经添加了 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.conf
的 nginx.conf 文件中定义了该指令,现在您需要在client_max_body_size
上添加/编辑指令http
的值或server
。
server {
client_max_body_size 100M;
...
}
设置好所需的值后,保存更改并重新加载 Nginx :service nginx reload
这些更改完成后,效果很好
答案 12 :(得分:0)
/**
* 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.
答案 13 :(得分:0)
你可以使用 cors 包来处理它。
var cors = require('cors')
var app = express()
app.use(cors())
用于设置具体的原点
app.use(cors({origin: 'http://localhost:8080'}));