我正在使用express在OpenShift上创建一个简单的Node应用程序(我只是修改了OpenShift的默认示例Node应用程序)。我希望得到CORS的支持:
var cors = require('cors');
...
/**
* Initialize the server (express) and create the routes and register
* the handlers.
*/
self.initializeServer = function() {
self.createRoutes();
self.app = express();
self.app.use(cors());
self.app.use(express.json());
// Add handlers for the app (from the routes).
for (var r in self.routes) {
self.app.get(r, self.routes[r]);
}
self.app.post('/vote/', function (req, res) {
// just echo back the request body
res.json(req.body);
});
};
如果我从本地机器发送请求,使用curl它可以正常工作:
C:\Users\Chin\Desktop>curl -H "Content-Type: application/json" -X POST -d "{\"username\":\"xyz\"}" https://bloodbrothers-chinhodado.rhcloud.com/vote/
{"username":"xyz"}
但是,如果我使用jQuery从另一个具有不同域的站点发送请求,则返回的正文为空:
$.ajax({
url: "https://bloodbrothers-chinhodado.rhcloud.com/vote/",
type: "POST",
crossDomain: true,
data: JSON.stringify({"username": "xyz"}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert(response);
},
error: function (xhr, status) {
alert("error");
}
});
=>服务器返回{}
我在console.log()
函数中放了一个self.app.post()
调用,实际上当请求来自跨域时,请求的主体是空的。
我在这里做错了什么?该应用程序是现场的,所以你可以尝试自己卷曲和ajax调用。
编辑:在这种情况下,如果我发出了CORS请求,它会进入self.app.post('/vote/', function (req, res) {}
函数(通过在console.log()
调用验证)。这是否意味着CORS运行良好而问题不在于CORS?
答案 0 :(得分:3)
我明白了。事实证明,像我一样启用CORS不起作用,因为content-type
是JSON,这使得该请求成为“复杂”请求。来自docs:
一个简单的跨站点请求是:
仅使用GET,HEAD或POST。如果使用POST将数据发送到服务器,则使用HTTP POST请求发送到服务器的数据的Content-Type是application / x-www-form-urlencoded,multipart / form-data或text / plain之一
不使用HTTP请求设置自定义标头(例如X-Modified等)
启用CORS Pre-Flight
某些CORS请求被视为“复杂”,需要初始OPTIONS请求(称为“飞行前请求”)。 “复杂”CORS请求的示例是使用除GET / HEAD / POST之外的HTTP动词(例如DELETE)或使用自定义标头的请求。要启用预先飞行,您必须为要支持的路由添加新的OPTIONS处理程序:
var express = require('express')
, cors = require('cors')
, app = express();
app.options('/products/:id', cors()); // enable pre-flight request for DELETE request
app.del('/products/:id', cors(), function(req, res, next){
res.json({msg: 'This is CORS-enabled for all origins!'});
});
所以我做了改动,现在工作得很好。