sails.js Getting a POST payload with text/plain content type

♀尐吖头ヾ 提交于 2020-01-02 16:06:07

问题


I'm developing a sails.js (node.js framework based on express) aplication, which is going great but ]I can't solve this detail...

I need to send POST requests cross domain from internet explorer 8 and 9. For that I'm forced to use xDomainRequest object, wich doesn't allow to set a Content type header.

So, when the request gets to the server the content type is "text/plain", which doesn't fire the bodyParser express middleware, so my req.body is an empty object and I can't see the payload I'm sending from the client.

For this I've tried two things with no luck:

First I wanted to set a header to the request in my first middleware, which is of course not available:

  req.set("Content-type", "Apli.....

Then, I created a middleware that listens to req.on('data'), like this:

        var data = "";
    req.on('data', function(chunk){ 
        data += chunk; 
    });
    req.on('end', function(){
       req.rawBody = data;
       next();
    });

But the data event never fires!

Does anyone know how can I access my raw payload, so I can parse it myself. Thanks!


回答1:


I think in this case you're going to have to implement your own body parser, which you can set as sails.config.express.bodyParser or create a config/express.js file like:

var express = require('express');
module.exports.express = {

   bodyParser: function(options) {

    // Get default body parser from Express
    var defaultBodyParser = express.bodyParser(options);

    // Get function for consumung raw body, yum.
    var getBody = require('raw-body');

    return function (req, res, next) {

        // If there's no content type, or it's text/plain, parse text
        if (!req.headers['content-type'] || 
            req.headers['content-type'].match('text/plain')) {

            // flag as parsed
            req._body = true;

            // parse
            getBody(req, {
              limit: 100000, // something reasonable here
              expected: req.headers['content-length']
            }, function (err, buf) {
              if (err) return next(err);

              // Make string from buffer
              buf = buf.toString('utf8').trim();

              // Set body
              req.body = buf.length ? {content: buf} : {}

              // Continue
              next();
            });
           }

         // Otherwise try the default parsers
         else return defaultBodyParser(req, res, next);         
    };


}

You'll have to npm install express and npm install raw-body. Note that this example uses the default Express body parser as a fallback, not the default Sails body parser which isn't exposed anywhere (and is mostly the same as Express anyway, sans the JSON retry).




回答2:


with newest version of Sails, using express is deprecated. I needed to use a specific parser to get raw data from Stripe API. Here is my code, maybe it will help somebody :

bodyParser: function(req, res, next) {
  var skipper = require('skipper')();
  var rawParser = require("body-parser").raw({type: "*/*"});

  // Create and return the middleware function
  return function(req, res, next) {
    sails.log.debug(req.headers);
    if (req.headers && req.headers['stripe-signature']) {
      sails.log.info('request using raw parser middleware');
      return rawParser(req, res, next);
    }
    // Otherwise use Skipper to parse the body
    sails.log.info('request using skipper middleware');
    return skipper(req, res, next);
  };
},


来源:https://stackoverflow.com/questions/21141664/sails-js-getting-a-post-payload-with-text-plain-content-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!