我试图在我的Node.js应用程序中支持使用Express.js Web框架的CORS。我已经阅读了a Google group discussion关于如何处理这个问题,并阅读了一些关于CORS如何工作的文章。首先,我这样做了(代码是用CoffeeScript语法编写的):
app.options "*", (req, res) ->
res.header 'Access-Control-Allow-Origin', '*'
res.header 'Access-Control-Allow-Credentials', true
# try: 'POST, GET, PUT, DELETE, OPTIONS'
res.header 'Access-Control-Allow-Methods', 'GET, OPTIONS'
# try: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'
res.header 'Access-Control-Allow-Headers', 'Content-Type'
# ...
它似乎不起作用。好像我的浏览器(Chrome)没有发送初始OPTIONS请求。当我刚刚更新资源块时,我需要将跨源GET请求提交到:
app.get "/somethingelse", (req, res) ->
# ...
res.header 'Access-Control-Allow-Origin', '*'
res.header 'Access-Control-Allow-Credentials', true
res.header 'Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS'
res.header 'Access-Control-Allow-Headers', 'Content-Type'
# ...
它有效(在Chrome中)。这也适用于Safari。
我读过......
在实现CORS的浏览器中,每个跨源GET或POST请求前面都有一个OPTIONS请求,用于检查GET或POST是否正常。
所以我的主要问题是,为什么在我的案例中似乎没有发生这种情况?为什么我的app.options块没有被调用?为什么我需要在主app.get块中设置标题?
要回答您的主要问题,如果POST或GET中包含任何非简单内容或标题,则CORS规范仅要求OPTIONS调用在POST或GET之前。
需要CORS pre-flight请求的内容类型(OPTIONS调用)是除以下内容之外的任何Content-Type:
application/x-www-form-urlencoded
multipart/form-data
text/plain
除上述内容之外的任何其他内容类型都将触发飞行前请求。
至于标题,除以下内容之外的任何请求标题都会触发飞行前请求:
Accept
Accept-Language
Content-Language
Content-Type
DPR
Save-Data
Viewport-Width
Width
任何其他请求标头将触发飞行前请求。
因此,您可以添加自定义标头,例如:x-Trigger: CORS
,这应该触发飞行前请求并点击OPTIONS块。
首先只需在项目中安装cors。将终端(命令提示符)和cd
带到项目目录并运行以下命令:
npm install cors --save
然后获取server.js文件并更改代码以在其中添加以下内容:
var cors = require('cors');
var app = express();
app.use(cors());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'DELETE, PUT, GET, POST');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
这对我有用..
这对我来说很有用,因为它在路线中很容易实现,我使用meanjs和它的工作正常,safari,chrome等。
app.route('/footer-contact-form').post(emailer.sendFooterMail).options(function(req,res,next){
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
return res.send(200);
});
前段时间,我遇到了这个问题所以我这样做是为了在我的nodejs app中允许CORS:
首先,您需要使用以下命令安装cors
:
npm install cors --save
现在将以下代码添加到您的应用程序启动文件中,如(app.js or server.js
)
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
}));
require('./router/index')(app);
如果您想使控制器特定,您可以使用:
res.setHeader('X-Frame-Options', 'ALLOWALL');
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'POST, GET');
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
请注意,这也将允许iframe。
Express 4.2.0(编辑:似乎在4.3.0中不起作用)我最简单的解决方案是:
function supportCrossOriginScript(req, res, next) {
res.status(200);
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Content-Type");
// res.header("Access-Control-Allow-Headers", "Origin");
// res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
// res.header("Access-Control-Allow-Methods","POST, OPTIONS");
// res.header("Access-Control-Allow-Methods","POST, GET, OPTIONS, DELETE, PUT, HEAD");
// res.header("Access-Control-Max-Age","1728000");
next();
}
// Support CORS
app.options('/result', supportCrossOriginScript);
app.post('/result', supportCrossOriginScript, function(req, res) {
res.send('received');
// do stuff with req
});
我想做app.all('/result', ...)
也会起作用......
可以参考下面的代码相同。资料来源:Academind/node-restful-api
const express = require('express');
const app = express();
//acts as a middleware
//to handle CORS Errors
app.use((req, res, next) => { //doesn't send response just adjusts it
res.header("Access-Control-Allow-Origin", "*") //* to give access to any origin
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization" //to give access to all the headers provided
);
if(req.method === 'OPTIONS'){
res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET'); //to give access to all the methods provided
return res.status(200).json({});
}
next(); //so that other routes can take over
})
除了其他人所说的,不要忘记,除非使用nodemon,否则您需要重新启动节点服务器才能使更改生效!
我个人一直在刷新我的浏览器习惯,忘记它是服务器端代码。
使用Express Middleware对我来说很有用。如果您已经在使用Express,只需添加以下中间件规则即可。它应该开始工作。
app.all("/api/*", function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
res.header("Access-Control-Allow-Methods", "GET, PUT, POST");
return next();
});
app.all("/api/*", function(req, res, next) {
if (req.method.toLowerCase() !== "options") {
return next();
}
return res.send(204);
});
在我的index.js
中,我补充说:
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
next();
})
我发现使用npm请求包(https://www.npmjs.com/package/request)非常容易
然后我基于http://blog.javascripting.com/2015/01/17/dont-hassle-with-cors/这个帖子我的解决方案
'use strict'
const express = require('express');
const request = require('request');
let proxyConfig = {
url : {
base: 'http://servertoreach.com?id=',
}
}
/* setting up and configuring node express server for the application */
let server = express();
server.set('port', 3000);
/* methods forwarded to the servertoreach proxy */
server.use('/somethingElse', function(req, res)
{
let url = proxyConfig.url.base + req.query.id;
req.pipe(request(url)).pipe(res);
});
/* start the server */
server.listen(server.get('port'), function() {
console.log('express server with a proxy listening on port ' + server.get('port'));
});
我发现最简单的方法是使用node.js包cors。最简单的用法是:
var cors = require('cors')
var app = express()
app.use(cors())
当然,有很多方法可以根据您的需要配置行为;上面链接的页面显示了许多示例。
这与Pat的答案类似,区别在于我用res.sendStatus(200)完成;而不是next();
代码将捕获方法类型OPTIONS的所有请求并发回access-control-headers。
app.options('/*', (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
res.sendStatus(200);
});
该代码接受来自问题中所请求的所有来源的CORS。但是,最好用特定的原点(即http://localhost:8080)替换*以防止误用。
由于我们使用app.options-method而不是app.use-method,因此我们不需要进行此检查:
req.method === 'OPTIONS'
我们可以在其他一些答案中看到。
以下为我工作,希望它能帮助别人!
const express = require('express');
const cors = require('cors');
let app = express();
app.use(cors({ origin: true }));
得到了https://expressjs.com/en/resources/middleware/cors.html#configuring-cors的参考
我们可以避免使用CORS并将请求转发给其他服务器:
// config:
var public_folder = __dirname + '/public'
var apiServerHost = 'http://other.server'
// code:
console.log("starting server...");
var express = require('express');
var app = express();
var request = require('request');
// serve static files
app.use(express.static(public_folder));
// if not found, serve from another server
app.use(function(req, res) {
var url = apiServerHost + req.url;
req.pipe(request(url)).pipe(res);
});
app.listen(80, function(){
console.log("server ready");
});
我使用以下步骤访问我的网络应用程序并取得了成功:
将cors包添加到express:
npm install cors --save
在bodyParser配置后添加以下行。我在bodyParser之前添加了一些麻烦:
// enable cors to the server
const corsOpt = {
origin: process.env.CORS_ALLOW_ORIGIN || '*', // this work well to configure origin url in the server
methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'], // to works well with web app, OPTIONS is required
allowedHeaders: ['Content-Type', 'Authorization'] // allow json and token in the headers
};
app.use(cors(corsOpt)); // cors for all the routes of the application
app.options('*', cors(corsOpt)); // automatic cors gen for HTTP verbs in all routes, This can be redundant but I kept to be sure that will always work.
在typescript中,如果你想使用node.js包cors
/**
* app.ts
* If you use the cors library
*/
import * as express from "express";
[...]
import * as cors from 'cors';
class App {
public express: express.Application;
constructor() {
this.express = express();
[..]
this.handleCORSErrors();
}
private handleCORSErrors(): any {
const corsOptions: cors.CorsOptions = {
origin: 'http://example.com',
optionsSuccessStatus: 200
};
this.express.use(cors(corsOptions));
}
}
export default new App().express;
如果您不想使用第三方库来进行cors错误处理,则需要更改handleCORSErrors()方法。
/**
* app.ts
* If you do not use the cors library
*/
import * as express from "express";
[...]
class App {
public express: express.Application;
constructor() {
this.express = express();
[..]
this.handleCORSErrors();
}
private handleCORSErrors(): any {
this.express.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-ALlow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
if (req.method === "OPTIONS") {
res.header(
"Access-Control-Allow-Methods",
"PUT, POST, PATCH, GET, DELETE"
);
return res.status(200).json({});
}
next(); // send the request to the next middleware
});
}
}
export default new App().express;
使用app.ts文件
/**
* server.ts
*/
import * as http from "http";
import app from "./app";
const server: http.Server = http.createServer(app);
const PORT: any = process.env.PORT || 3000;
server.listen(PORT);
const express = require("express");
const router = express.Router();
const app = express();
const cors = require("cors");
const options = {
origin: true,
"Access-Control-Allow-Credentials": true,
"Access-Control-Allow-Origin": true,
"Access-Control-Allow-Headers": true,
"Access-Control-Expose-Headers": true
};
app.use(cors(options));
router.get("/", cors(options), (req, res) => {
res.render("index", { title: "Express" });
});
module.exports = router;
对于GOOGLE CHROME,您需要添加“Allow-Control-Allow-Origin”扩展名
Access-Control-Allow-Origin(响应头)头通过返回Origin请求头的值来指示资源是否可以基于SHARED。 Access-Control-Allow-Origin标题为跨源访问打开了一扇门
Access-Control-Allow-Credentials(响应标头):true用于指示允许客户端使用凭据。默认情况下,客户端脚本无法读取对凭证请求的响应。所以你可以访问响应。此外,默认情况下,CORS不会在跨源请求中包含Cookie,这可能会导致一类称为跨站点请求伪造或CSRF的漏洞。为了减少CORS中CSRF漏洞的可能性,CORS要求服务器和客户端都承认可以在请求中包含cookie。
Access-Control-Expose-Headers(响应标头)指示哪些标头可以安全公开。可以读取响应中的标头列表。默认情况下,仅公开6个简单响应标头:Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma
Access-Control-Request-Headers(请求标头)指示在实际请求期间可以使用哪些HTTP标头。
origin = true(请求标头)反映请求源。如果是假的,Cors将被禁用。
下面的代码可以使用,但首先安装cors:
npm install --save cors
然后:
module.exports = function(app) {
var express = require("express");
var cors = require('cors');
var router = express.Router();
app.use(cors());
app.post("/movies",cors(), function(req, res) {
res.send("test");
});
使用没有快速/外部库的nodejs我在server.js文件中使用了下面的方法。这里的关键部分是从请求头获取原点,然后在服务器响应中允许它,此时我们可以设置将返回的头,包括找到匹配时允许的源。
**const origin = req.headers.origin;**
let decoder = new StringDecoder('utf-8');
let buffer = '';
req.on('data', function (data) {
buffer += decoder.write(data);
});
req.on('end', function () {
buffer += decoder.end();
let chosenHandler = typeof (server.router[trimmedPath]) !== 'undefined' ? server.router[trimmedPath] : handlers.notFound;
const data = { ....data object vars}
// should be wrapped in try catch block
chosenHandler(data, function (statusCode, payload, contentType) {
server.processHandlerResponse(res, method, trimmedPath, statusCode, payload, contentType, **origin**);
server.processHandlerResponse = function (res, method, trimmedPath, statusCode, payload, contentType, origin) {
contentType = typeof (contentType) == 'string' ? contentType : 'json';
statusCode = typeof (statusCode) == 'number' ? statusCode : 200;
let payloadString = '';
if (contentType == 'json') {
res.setHeader('Content-Type', 'application/json');
const allowedOrigins = ['https://www.domain1.com', 'https://someotherdomain','https://yetanotherdomain',
...// as many as you need
];
**if (allowedOrigins.indexOf(origin) > -1) {
res.setHeader('Access-Control-Allow-Origin', origin);
}**
payload = typeof (payload) == 'object' ? payload : {};
payloadString = JSON.stringify(payload);
}
... // if (other content type) ...rinse and repeat..
最简单的方法是使用以下方法在项目中安装cors模块:
npm i --save cors
然后在您的服务器文件中使用以下命令导入它:
import cors from 'cors';
然后简单地将它用作这样的中间件:
app.use(cors());
希望这可以帮助!
尝试将控制权传递给下一个匹配的路线。如果Express首先匹配app.get路由,那么它将不会继续进入选项路由,除非你这样做(注意使用next):
app.get('somethingelse', function(req, res, next) {
//..set headers etc.
next();
});
在组织CORS的方面,我把它放在一个适合我的中间件中:
//CORS middleware
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'example.com');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
//...
app.configure(function() {
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'cool beans' }));
app.use(express.methodOverride());
app.use(allowCrossDomain);
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
保持路由的相同想法。我用这个代码:
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
做
npm install cors --save
并在您的主文件中添加这些行,您的请求将继续(在任何路由之前保留它)。
const cors = require('cors');
const express = require('express');
let app = express();
app.use(cors());
app.options('*', cors());
我已经制作了一个更完整的中间件,适合快递或连接。它支持OPTIONS
预检检查请求。请注意,它允许CORS访问任何内容,如果要限制访问,可能需要进行一些检查。
app.use(function(req, res, next) {
var oneof = false;
if(req.headers.origin) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
oneof = true;
}
if(req.headers['access-control-request-method']) {
res.header('Access-Control-Allow-Methods', req.headers['access-control-request-method']);
oneof = true;
}
if(req.headers['access-control-request-headers']) {
res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
oneof = true;
}
if(oneof) {
res.header('Access-Control-Max-Age', 60 * 60 * 24 * 365);
}
// intercept OPTIONS method
if (oneof && req.method == 'OPTIONS') {
res.send(200);
}
else {
next();
}
});
安装expressjs的cors模块。你可以按照这些步骤>
安装
npm install cors
简单用法(启用所有CORS请求)
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
欲了解更多详情,请访问https://github.com/expressjs/cors
做这样的事情:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
使用express + node + ionic在不同端口运行完成测试。
Localhost:8100
Localhost:5000
// CORS (Cross-Origin Resource Sharing) headers to support Cross-site HTTP requests
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});