POST 使用 CORS 和 OpenShift 上的节点应用程序清空请求正文

Empty request body with POST using CORS with a node app on OpenShift

我正在使用 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");
    }
});

=>服务器returns{}

我在 self.app.post() 函数中放置了一个 console.log() 调用,确实当请求来自跨域时,请求的主体是空的。

我这里做错了什么?该应用程序已上线,因此您可以尝试使用 curl,如果需要,还可以 ajax 给自己打电话。

编辑: 在这种情况下,如果我发出 CORS 请求,它会进入 self.app.post('/vote/', function (req, res) {} 函数(通过调用 console.log() 进行验证那里)。这是否意味着 CORS 运行良好并且问题不是因为 CORS?

我明白了。事实证明,像我一样启用 CORS 是行不通的,因为 content-type 是 JSON,这使得该请求成为“复杂”请求。来自 docs:

A simple cross-site request is one that:

  • Only uses GET, HEAD or POST. If POST is used to send data to the server, the Content-Type of the data sent to the server with the HTTP POST request is one of application/x-www-form-urlencoded, multipart/form-data, or text/plain.

  • Does not set custom headers with the HTTP Request (such as X-Modified, etc.)

和来自 npm cors package doc

Enabling CORS Pre-Flight

Certain CORS requests are considered 'complex' and require an initial OPTIONS request (called the "pre-flight request"). An example of a 'complex' CORS request is one that uses an HTTP verb other than GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable pre-flighting, you must add a new OPTIONS handler for the route you want to support:

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!'});
});

所以我进行了更改,现在运行良好。