我试图在使用Express.js web框架的Node.js应用程序中支持CORS。我已经阅读了谷歌关于如何处理这个问题的小组讨论,并阅读了一些关于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)没有发送最初的选项请求。当我刚刚更新了块的资源,我需要提交一个跨起源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块设置标题?
在你的主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();
});
这应该能解决你的问题
我对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',…)也可以…
在typescript中,如果你想使用node.js包cors .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);