我正在尝试在使用 Express.js Web 框架的 Node.js 应用程序中支持 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 块中设置标题?
我发现最简单的方法是使用 node.js 包 cors。最简单的用法是:
var cors = require('cors')
var app = express()
app.use(cors())
当然,有很多方法可以根据您的需要配置行为;上面链接的页面显示了许多示例。
尝试将控制权传递给下一个匹配的路线。如果 Express 首先匹配 app.get 路由,那么除非您这样做(注意使用 next),否则它将不会继续使用 options 路由:
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'));
});
config.allowedDomains
是逗号分隔的字符串还是数组?
为了回答您的主要问题,如果 POST 或 GET 中包含任何非简单的内容或标题,CORS 规范仅要求 OPTIONS 调用位于 POST 或 GET 之前。
需要 CORS 飞行前请求(OPTIONS 调用)的 Content-Type 是任何 Content-Type,但以下内容除外:
application/x-www-form-urlencoded multipart/form-data text/plain
除了上面列出的内容类型之外的任何其他内容类型都将触发飞行前请求。
至于 Headers,除以下之外的任何 Request Headers 都会触发 pre-flight 请求:
Accept-Language Content-Language Content-Type DPR Save-Data Viewport-Width 宽度
任何其他请求标头都将触发飞行前请求。
因此,您可以添加一个自定义标头,例如:x-Trigger: CORS
,这应该会触发飞行前请求并点击 OPTIONS 块。
请参阅MDN Web API Reference - CORS Preflighted requests
OPTIONS
块不发送的一般条件。如果它有接受的 HEADERS
的列表,或者哪个 content-types
需要 OPTIONS
等,那就太好了,但这是一个好的开始
保持路由的相同想法。我使用这段代码:
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 示例
做
npm install cors --save
并将这些行添加到您的请求所在的主文件中(保留在任何路线之前)。
const cors = require('cors');
const express = require('express');
let app = express();
app.use(cors());
app.options('*', cors());
app.options('*', cors())
// 在其他路由之前包含
我做了一个比较完整的适合express或connect的中间件。它支持 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();
}
});
做这样的事情:
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();
});
安装 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: Cannot read property 'headers' of undefined
最基本的应用设置。
使用在不同端口中运行的 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();
});
首先只需在您的项目中安装 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
是一个为您处理所有这些的库。删除您的第一个 &第 3 行(也就是 cors
的所有内容),您会发现它仍然有效。
res.header("Access-Control-Allow-Origin", "*");
前段时间,我遇到了这个问题,所以我这样做是为了在我的 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);
这对我有用,因为它在路线内很容易实现,我使用 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);
});
如果要使其特定于控制器,可以使用:
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。
在我的 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,请不要使用它。
可以参考下面的代码。来源: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
})
const app = express();
之后并且工作!我认为提及它很重要。
最简单的答案是只使用 cors package。
const cors = require('cors');
const app = require('express')();
app.use(cors());
这将全面启用 CORS。如果您想学习如何enable CORS without outside modules,您真正需要的只是一些设置 'Access-Control-Allow-Origin' header 的 Express middleware。这是允许从浏览器到服务器的跨请求域的最低要求。
app.options('*', (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
res.send('ok');
});
app.use((req, res) => {
res.set('Access-Control-Allow-Origin', '*');
});
cors
包是解决 express.js 中 CORS 政策问题的推荐方法,但您还需要确保为 app.options
启用它,如下所示:
const cors = require('cors');
// enable cors
app.use(
cors({
origin: true,
optionsSuccessStatus: 200,
credentials: true,
})
);
app.options(
'*',
cors({
origin: true,
optionsSuccessStatus: 200,
credentials: true,
})
);
我最简单的 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', ...)
也可以...
下面对我有用,希望对某人有所帮助!
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 文件中试试这个:
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();
});
这应该可以解决您的问题
在 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);
使用 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);
});
使用 CORS
包。并把这个参数:
cors({credentials: true, origin: true, exposedHeaders: '*'})
auth-token
标头在响应标头中可见的确切答案
我发现使用 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'));
});
这与 Pat 的回答类似,不同之处在于我以 res.sendStatus(200); 结尾。而不是下一个();
该代码将捕获方法类型 OPTIONS 的所有请求并发送回访问控制标头。
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'
我们可以在其他一些答案中看到。
我在这里找到了答案:http://johnzhang.io/options-request-in-express。
最简单的方法是使用以下命令在项目中安装 cors 模块:
npm i --save cors
然后在您的服务器文件中使用以下命令导入它:
import cors from 'cors';
然后简单地将它用作这样的中间件:
app.use(cors());
希望这可以帮助!
简单很难:
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))
})
如果你想在没有 cors NPM 包的情况下让 CORS 工作(为了纯粹的学习乐趣!),你绝对可以自己处理 OPTIONS 调用。这对我有用:
app.options('*', (req, res) => {
res.writeHead(200, '', {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS',
}).end();
});
很好很简单,对吧?请注意使用 res.writeHead() 而不是 res.header(),这是我不熟悉的。
如果您的 Express 服务器启用了授权,您可以像这样实现
const express = require('express');
const app=express();
const cors=require("cors");
app.use(cors({
credentials: true, // for authorization
}));
...
我们可以避免 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({credentials: true, origin: true})
cors({credentials: true, origin: true})
!这相当于取消同源政策。非常不安全。