我已经使用 Node/Express 创建了一个小型 API,并尝试使用 Angularjs 提取数据,但由于我的 html 页面在 localhost:8888 上的 apache 下运行,并且节点 API 在端口 3000 上侦听,我没有得到没有"访问控制-允许-来源"。我尝试使用node-http-proxy
和Vhosts Apache,但没有太多成功,请参阅下面的完整错误和代码。
XMLHttpRequest 无法加载 localhost:3000。请求的资源上不存在"访问控制允许源"标头。因此,不允许访问源'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>
尝试将以下中间件添加到您的 NodeJS/Express 应用程序中(为了您的方便,我添加了一些注释(:
// 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();
});
(您可能需要使用 127.0.0.1
而不是 localhost
。
的答案很好,如果您更喜欢更短的内容,您可以使用可用于 Express.js 的名为 cors 的插件。
对于这种特殊情况,它使用起来很简单:
var cors = require('cors');
// use it before all route definitions
app.use(cors({origin: 'http://localhost:8888'}));
(您可能需要使用 127.0.0.1
而不是 localhost
。
需要与允许的源匹配,您还可以有多个请求源:
app.use(
cors({origin: ['http://localhost:8888', 'http://127.0.0.1:8888']})
);
另一种方法是简单地将标头添加到您的路由中:
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:)');
});
最高答案对我来说效果很好,除了我需要将多个域列入白名单。
此外,顶级答案受到以下事实的影响: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);
});
应答码只允许本地主机: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();
});
在项目中安装 cors 依赖项:
npm i --save cors
将以下内容添加到服务器配置文件中:
var cors = require('cors');
app.use(cors());
它适用于我的 2.8.4 cors 版本。
当前端和后端在不同的端口上运行时,就会发生这种情况。由于 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
我有用。
app.get('/', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.send('hello world')
})
您可以更改 * 以满足您的需求。希望这能有所帮助。
所有其他答案都对我不起作用。(包括 CORS 包,或通过中间件设置标头(
对于 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"]
}
});
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();
}
});
在 NODEJ Restful API 的 app.js 中添加以下代码,以避免在 angular 6 或任何其他框架中出现"访问控制-允许-原产地"错误
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
}));
你可以使用 cors 包来处理它。
var cors = require('cors')
var app = express()
app.use(cors())
用于设置特定原点
app.use(cors({origin: 'http://localhost:8080'}));
了解更多
您可以使用"$http.jsonp">
或
以下是用于本地测试的 chrome 解决方法
您需要使用以下命令打开镶边。(按窗口+R(
Chrome.exe --allow-file-access-from-files
注意:您的镶边不得打开。当您运行此命令时,chrome 将自动打开。
如果您在命令提示符下输入此命令,请选择您的 chrome 安装目录,然后使用此命令。
以下脚本代码用于在MAC中打开chrome,带有"--allow-file-access-from-files">
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
/**
* 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.
除了所有列出的答案外,我还有相同的错误
我可以访问前端和后端,我已经添加了 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
在这些更改之后,它运行良好
参考资料: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(。
我们将看看前 2 个答案是否接受我的编辑,但很可能您必须添加或使用127.0.0.1
而不是localhost
。
cors
包,您甚至可以使用多个允许的源:
app.use(
cors({ origin: ["http://localhost:8888", "http://127.0.0.1:8888"] })
);
如果您希望允许任何事情,您可以使用origin: "*"
。
有关更多信息,请查看 Web 开发简化版的教程。