脊椎、node.js (express) 和 Access-Control-Allow-Origin
Posted
技术标签:
【中文标题】脊椎、node.js (express) 和 Access-Control-Allow-Origin【英文标题】:spine, node.js (express) and Access-Control-Allow-Origin 【发布时间】:2012-04-22 02:51:30 【问题描述】:我正在本地电脑上开发一个应用程序。前端应该使用 spinjs 构建,后端 API 应该使用 node.js。 Spine 在端口 9294 上运行,node.js 在端口 3000 上运行。 在 Spine 中,我在模型中添加了以下内容:
@url: "http:localhost:3000/posts"
在我的快递服务器中
app.get('/posts', function(req, res)
console.log("giving ALL the posts");
res.header("Access-Control-Allow-Origin", "*")
res.json(posts);
);
但我总是在 chrome 中收到以下错误:
XMLHttpRequest cannot load http://localhost:3000/posts. Origin http://localhost:9294 is not allowed by Access-Control-Allow-Origin.
我必须做什么才能正确访问我的 api?我虽然在响应中添加标题确实可以解决问题。
【问题讨论】:
您是否检查了响应标头以确认标头确实已设置?此外,jQuery 使用 'OPTIONS' HTTP 命令来检测预授权;确保 express 也响应该 HTTP 动词 老实说,我的请求似乎永远不会到达我的 node.js 服务器。在将任何内容发送到客户端之前,我在 app.get() 中添加了一个调试语句。直接通过 url 访问我的 api 时,我可以看到该语句,但通过 spin 访问时看不到 你应该使用像 charles 这样的东西来确保这种情况发生。我们在这里做了很多 x 域的事情,直到您看到没有设置标头,这令人沮丧。 【参考方案1】:app.get
只会响应GET
请求。如果浏览器使用OPTIONS
请求对其进行预检,express 将发送错误,因为它没有任何侦听器来处理这些请求。尝试在您的代码之外添加此代码,看看它是否有效:
app.options('/posts', function(req, res)
console.log("writing headers only");
res.header("Access-Control-Allow-Origin", "*");
res.end('');
);
另请注意:如果您在请求中发送 cookie (withcredentials=true
),则 Access-Control-Allow-Origin
标头不能是 *
,它必须是浏览器自动添加的 Origin
标头中的确切值像这样的ajax请求:
res.header("Access-Control-Allow-Origin", req.headers.origin);
这是出于安全原因 - 如果您正在执行需要 cookie 的操作,那么您更有可能需要实际检查 origin
是否是允许的网站,以避免 CSRF attacks。
【讨论】:
【参考方案2】:此中间件将允许 CORS 使用 Express,关键是检测预检请求 OPTIONS
并返回响应以避免 404 或重复的数据库查询。
见资源:http://cuppster.com/2012/04/10/cors-middleware-for-node-js-and-express/
var methodOverride = require('method-override');
app.use(methodOverride());
// ## CORS middleware
// see: http://***.com/questions/7067966/how-to-allow-cors-in-express-nodejs
var allowCrossDomain = function(req, res, next)
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
// intercept OPTIONS method
if ('OPTIONS' == req.method)
res.send(200);
else
next();
;
app.use(allowCrossDomain);
【讨论】:
methodOverride 从版本 4 开始不再与 Express 捆绑,因此您需要在 package.json 中包含“method-override”,然后使用app.use(express.methodOverride())
代替 var methodOverride = require('method-override'); app.use(methodOverride());
跨度>
以上是关于脊椎、node.js (express) 和 Access-Control-Allow-Origin的主要内容,如果未能解决你的问题,请参考以下文章
UnhandledPromiseRejectionWarning、Express.js 和 Node.js