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中)。在Safari中也可以使用。
我读到了...
在实现CORS的浏览器中,每个跨域的GET或POST请求都带有前缀一个OPTIONS请求,检查GET或POST是否正常。
所以我的主要问题是,在我看来,这似乎没有发生吗?为什么没有调用我的app.options块?为什么需要在主app.get块中设置标题?
#1 楼
要回答您的主要问题,如果POST或GET中包含任何非简单的内容或标头,则CORS规范仅要求OPTIONS调用位于POST或GET之前。内容类型需要一个除以下内容外,CORS飞行前请求(OPTIONS调用)是任何Content-Type:
application/x-www-form-urlencoded
multipart/form-data
text/plain
除上面列出的内容类型外,任何其他Content-Type都将触发飞行前请求。对于标题,除以下内容外,任何请求标头都将触发飞行前请求:
Accept
Accept-Language
Content-Language
Content-Type
DPR
Save-Data
Viewport-Width
Width
其他任何请求标头都将触发飞行前请求。
因此,您可以添加一个自定义标头,例如:
x-Trigger: CORS
,这将触发飞行前请求并点击OPTIONS块。 请参阅MDN Web API参考-CORS预检请求
评论
你能举个例子吗?
– Glen Pierce
18年4月29日在17:53
我链接到的页面似乎有很多示例。您能告诉我您认为缺少哪个例子吗?
– Dobes Vandermeer
18年4月30日在19:26
但总的来说,仅链接的答案很脆弱,因为它们随时可能被破坏。就是说,这个答案似乎足够好,因为它突出显示了OPTIONS块不发送的一般条件。如果它具有可接受的HEADERS列表,或者哪些内容类型需要OPTIONS等,那会很好,但这是一个好的开始
–dwanderson
18年6月19日在1:38
#2 楼
我发现最简单的方法是使用node.js包cors。最简单的用法是:var cors = require('cors')
var app = express()
app.use(cors())
当然,有很多方法可以根据您的需要配置行为。上面链接的页面显示了许多示例。
评论
当我将其与凭据一起使用时,它对我来说失败。 :(其他所有东西都像一个咒语。。但是如果凭据设置为true失败,它对我来说毫无用处
– Sambhav Sharma
14年6月27日在22:15
它对ajax请求的工作正常。我想要针对脚本标签和iFrame的CORS实现,因为在这些请求中,请求标头中不存在Origin :(如何实现这一点?
– akashPatra
2014年8月20日在7:50
您还需要设置cors({credentials:true,origin:true})
–劳森
2014年11月4日15:49
如何在此处启用选项预检?
–碎肉
18/12/19在6:55
@nlawson啊,你救了我
– Adrin
18/12/23在15:24
#3 楼
尝试将控制权传递给下一条匹配的路线。如果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'));
});
评论
我相信OPTIONS会在GET之前发生,但是如果您正在执行POST-没有OPTIONS请求...
–尼克
2011年9月13日15:14
config.allowedDomains是逗号分隔的字符串还是数组?
– pixelfreak
2012年11月17日下午2:56
config.allowedDomains应该是一个空格分隔的数组
–mcfedr
13年3月20日在8:10
通过简单地重新排列明确的中间件顺序就删除了多余的会话。另一方面,这需要更多的安全性。如果来源不在允许的域中,则请求仍会被处理,只有浏览器无法看到请求,并且来源会被欺骗。我的建议是进行检查,如果原点不在允许的列表中,请立即返回403。也是正在提供任何敏感信息,通过会话验证用户。
– Xerri
2013年9月19日上午10:52
@mcfedr您能否解释一下空格分隔的数组是什么意思?
–tkit
2014年3月26日20:27在
#4 楼
保持相同的路由思想。我使用此代码:app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
与http://enable-cors.org/server_expressjs.html示例类似
评论
这放在grunt.js文件中吗?
–奥利弗·迪克森(Oliver Dixon)
2015年1月2日,2:13
那飞行前呢?
–后台
15年2月4日在13:01
没有@OliverDixon,这是在服务器端
–亚历山大·马格诺·泰勒斯·齐默勒(Alexandre Magno Teles Zimerer)
19年7月4日在22:17
#5 楼
做npm install cors --save
,然后将这些行添加到您的请求所要移至的主文件中(保留在任何路由之前)。
const cors = require('cors');
const express = require('express');
let app = express();
app.use(cors());
app.options('*', cors());
评论
app.options('*',cors())//在其他路由之前包含
–拉耶什瓦尔
18年11月12日在10:47
#6 楼
我做了一个更完整的中间件,适合表达或连接。它支持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();
}
});
评论
嘿,我遇到了您的解决方案,想知道如果未检测到标头之一,是否应将'oneof'标志设置为false?
– Leonidas
13年3月19日在21:14
某些请求将不具有所有标题。具体来说,浏览器会发送GET请求,当它没有获得正确的allow-origin响应时,就会给js错误。而对于POST请求,则首先发送带有allow-method头的OPTIONS请求,然后才发送实际的POST请求。
–mcfedr
13年3月20日在8:06
知道了谢谢。如果req方法是“ options”,您是否曾经因为没有在其中放置res.send(200)而遇到麻烦?
– Leonidas
2013年3月20日14:24
我认为我没有尝试发送其他内容,我想其他任何响应都会导致浏览器拒绝该请求。
–mcfedr
13年3月20日在15:19
就像魅力一样工作,我只是添加一个授权域列表以提高安全性
– Sebastien H.
18年4月11日在10:26
#7 楼
安装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
评论
TypeError:无法读取未定义的属性“标头”最基本的应用程序设置。
–奥利弗·迪克森(Oliver Dixon)
17年12月3日,19:51
您确定您有请求对象吗? :)
–基于代码
18年4月12日在23:25
#8 楼
做这样的事情: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();
});
#9 楼
使用在不同端口中运行的Express +节点+离子进行的测试。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();
});
评论
我们需要在哪个文件中添加这些行?
– Shefalee Chaudhary
16 Dec 15'在10:24
#10 楼
首先只需在您的项目中安装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();
});
这对我有用。.
评论
如果您正在做res.header的东西,则不需要cors。 cors是一个为您处理所有事务的库。删除第一行和第三行(也就是带有cors的所有内容),您会发现它仍然有效。
–thisissami
17年9月7日在19:25
哎呀,我很确定您真正需要的是这行res.header(“ Access-Control-Allow-Origin”,“ *”);
–thisissami
17年9月7日在19:26
不过请记住,这样做会损害您的安全性。 :)
–thisissami
17年9月7日在19:27
#11 楼
前一段时间,我遇到了这个问题,所以我这样做是为了在我的nodejs应用程序中允许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);
评论
在安装cors后尝试了此操作。 Cors不是功能
–科林·里克尔斯
18年7月6日在13:27
#12 楼
这对我来说很有效,因为它在路由中很容易实现,因此我使用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);
});
#13 楼
如果要使其特定于控制器,则可以使用: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。
#14 楼
可以参考下面的代码。来源:Academind / node-restful-apiconst 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
})
评论
我看到了很多答案,其中有些是很重要的,我尝试在某些其他配置之后使用这部分代码,但由于某些原因,我尝试将代码放在app const app = express()之后。和工作!我认为提及这一点很重要。
–rfcabal
19年1月13日,0:45
#15 楼
最简单的答案是只使用cors软件包。const cors = require('cors');
const app = require('express')();
app.use(cors());
这将全面启用CORS。如果您想了解如何在不使用外部模块的情况下启用CORS,则您真正需要的是一些Express中间件,该中间件设置了“ Access-Control-Allow-Origin”标头。这是允许从浏览器到服务器的跨请求域的最低要求。
app.options('*', (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
res.send('ok');
});
app.use((req, res) => {
res.set('Access-Control-Allow-Origin', '*');
});
#16 楼
在我的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();
})
评论
我应该评论一下Access-Control-Allow-Origin = *意味着您将无法将Cookie发送到服务器,但它们会被CORS政策拒绝-来源:developer.mozilla.org/en-US/docs / Web / HTTP /…。因此,如果要使用Cookie,请不要使用此功能。
– Eksapsy
19年8月19日在13:59
#17 楼
我用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', ...)
也可以。 。#18 楼
使用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);
});
参考
#19 楼
以下对我有用,希望对您有所帮助!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
评论
那会进入什么文件?花生酱.js?
–安德鲁·科珀(Andrew Koper)
19年3月18日在18:12
不知道花生酱.js,对我来说就是express.js。基本上,它应该是您需要Express应用程序,对其进行初始化以及需要路由文件的文件。
–Vatsal Shah
19 Mar 19 '19在5:02
#20 楼
我发现使用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'));
});
#21 楼
在打字稿中,如果要使用cors的node.js包/**
* 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);
评论
“如果服务器是用打字稿编写的” —否。问题说它是用CoffeeScript编写的。
–昆汀
18年7月9日在9:44
@Quentin我只想显示打字稿中的替代字,希望这可以对某人有所帮助。
–胜任者
18年7月9日在9:49
#22 楼
这与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-,因此方法,我们不需要进行此检查:
req.method === 'OPTIONS'
我们可以在其他一些答案中看到。
我在这里找到了答案:http://johnzhang.io/options-request-in-express。
#23 楼
最简单的方法是使用以下命令在项目中安装cors模块:npm i --save cors
然后在服务器文件中使用以下命令将其导入:
import cors from 'cors';
然后只需将其用作这样的中间件即可:
app.use(cors());
希望有帮助!
#24 楼
您可以使用Express中间件,阻止您的域和方法。app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", process.env.DOMAIN); // update to match the domain you will make the request from
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
});
#25 楼
简单很难: let my_data = []
const promise = new Promise(async function (resolve, reject) {
axios.post('https://cors-anywhere.herokuapp.com/https://maps.googleapis.com/maps/api/directions/json?origin=33.69057660000001,72.9782724&destination=33.691478,%2072.978594&key=AIzaSyApzbs5QDJOnEObdSBN_Cmln5ZWxx323vA'
, { 'Origin': 'https://localhost:3000' })
.then(function (response) {
console.log(`axios response ${response.data}`)
const my_data = response.data
resolve(my_data)
})
.catch(function (error) {
console.log(error)
alert('connection error')
})
})
promise.then(data => {
console.log(JSON.stringify(data))
})
#26 楼
我们可以避免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");
});
评论
这不能回答所问的问题
– david.barkhuizen
18年1月16日在12:53
#27 楼
我对Web应用程序执行了以下步骤,并获得了成功:将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.
#28 楼
如果我是@OP,那么我将更改我的编程范例。假设您正在向localhost或类似的对象发出请求,则会阻塞这些CORS。
最终,如果您即将部署到
Google Cloud Platform
或Heroku
或的生产视蛋白,您将不必担心CORS,例如在生产时允许来源或其他任何原因。因此,在测试服务器时,只需使用
postman
,您就不会在部署服务器之后,然后在您的客户端上工作,将CORS阻止。#29 楼
/ *首先,这可能是像我这样的初级开发人员之间的问题:请确保在您的提取方法中使用“ lambda” >>>>“`”而不是“'”! * /```const response = await fetch(
https://api....
); / plus,强烈建议以下文章:https://developer.edamam.com/ api / faq /
#30 楼
在您的主要js文件中尝试以下操作:app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method"
);
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE");
res.header("Allow", "GET, POST, OPTIONS, PUT, DELETE");
next();
});
这应该可以解决您的问题
评论
CoffeeScript的黄金法则是:“这只是JavaScript”。这个答案可能有用:stackoverflow.com/a/58064366/7059557