允许向 Heroku 上的 Express/Node.js 应用程序发送 CORS REST 请求

我已经在 node.js 的 Express 框架上编写了一个 REST API,它可以处理来自 Chrome 中 js 控制台的请求,以及 URL 栏等。我现在试图让它工作的请求从另一个应用程序,在一个不同的域(CORS)。

由 javascript 前端自动发出的第一个请求是/api/search? uri = ,在“预飞行”选项请求上似乎失败了。

在我的快递应用程序中,我添加 CORS 头,使用:

var allowCrossDomain = function(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');


// intercept OPTIONS method
if ('OPTIONS' == req.method) {
res.send(200);
}
else {
next();
}
};

以及:

app.configure(function () {
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(allowCrossDomain);
app.use(express.static(path.join(application_root, "public")));
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

在 Chrome 控制台上,我看到了这些标题:

请求网址: http://furious-night-5419.herokuapp.com/api/search?uri=http%3a%2f%2flocalhost%3a5000%2fcollections%2f1%2fdocuments%2f1

请求方法: 选项

状态代码: 200 OK

请求标题

Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:origin, x-annotator-auth-token, accept
Access-Control-Request-Method:GET
Connection:keep-alive
Host:furious-night-5419.herokuapp.com
Origin:http://localhost:5000
Referer:http://localhost:5000/collections/1/documents/1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5

查询字符串参数

uri:http://localhost:5000/collections/1/documents/1

回应标题

Allow:GET
Connection:keep-alive
Content-Length:3
Content-Type:text/html; charset=utf-8
X-Powered-By:Express

这看起来像是 API 应用程序发送的正确报头的缺失吗?

谢谢。

87255 次浏览

I've cheked your code on a clean ExpressJS app and it works just fine.

Try move your app.use(allowCrossDomain) to the top of configure function.

for supporting cookies withCredentials you need this line xhr.withCredentials = true;

mdn docs xhr.withCredentials

In the Express Server add this block before all the other

`app.all('*', function(req, res, next) {
var origin = req.get('origin');
res.header('Access-Control-Allow-Origin', origin);
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});`

It could not be the case for most people browsing this question but I had this exact same problem and the solution was not related to CORS.

Turns out that JSON Web Token secret string was not defined in the environment variables, so the token could not be signed. This caused to any POST request that relies on checking or signing a token to get a timeout and return a 503 error, telling the browser that there's something wrong in CORS, which it's not. Adding the environment variable in Heroku solved the issue.

I hope this helps someone.

I'm adding this as an answer only because the original post was put in as a comment and as such it got overlooked by yours truly the first time I went over this page.

As @ConnorLeech points out in his comment to the accepted answer above, there is a very handy npm package called, not surprisingly, cors. It's use is as simple as var cors = require('cors'); app.use(cors()); (again, cribbed from Mr. Leech's answer) and can also be applied in a stricter, more configurable fashion as outlined in their docs.

It may also be worth pointing out that the original comment I refer to above was made in 2014. It's 2019 now and looking at the npm package's github page the repo was updated as recently as nine days ago.

enter image description here

Follow the below steps:

npm install cors --save

Inside your root js file:

 var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())

The Cors error could be a cover up for your actual error. Look in the logs of your heroku build to see your potential real error. Mine was this.

Heroku Postgres: "psql: FATAL: no pg_hba.conf entry for host"