Node.js - POST 中的 req.on("data") 永远不会被调用,即使 req.body 不为空

Node.js - req.on("data") in POST is never called even though req.body is not empty

我正在执行以下操作:

......
....
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({  
  extended: true 
})); 

app.use('/public', express.static(__dirname + '/public'));

app.post('/uninstalled', function (req, res, next)
{     
  var bodyAsQueryString = queryString.stringify(req.body);
  console.log('bodyAsQueryString = ' + bodyAsQueryString);

  var hmacReceived = req.headers['x-shopify-hmac-sha256'];
  var calculatedHmac = crypto.createHmac('SHA256', config.app.secret);

  req.on("data", function(data) 
  {
     console.log('on data...');
     calculatedHmac.update(data);
  });

  req.on("end", function() 
  {
     console.log('on end...');
     calculatedHmac = calculatedHmac.digest("base64");
     console.log('hmacReceived = ' + hmacReceived);
     console.log('calculatedHmac = ' + calculatedHmac);
  });

  req.on("error", function(err) 
  {
     console.log('on error...');
     console.log(err);
     return next(err);
  });
});
上面 req.on("...")

None 曾经被调用过(控制台没有记录任何内容...)-我做错了什么?

bodyAsQueryString 的值总是如下所示(我用 xxxxx 替换了个人数据):

id=xxxxx&name=xxxxx&email=xxxxxx&domain=xxxxxxx&created_at=2015-03-21T00%3A31%3A36%2B00%3A00&province=&country=GB&address1=xxxxxxxxx&zip=E59JY&city=London&source=xxxx&phone=xxxxxx&updated_at=2015-08-19T15%3A12%3A31%2B01%3A00&customer_email=&latitude=xxxxx&longitude=-xxxxxx&primary_location_id=&primary_locale=en&country_code=GB&country_name=United%20Kingdom&currency=USD&timezone=(GMT%2B00%3A00)%20Europe%2FLondon&iana_timezone=Europe%2FLondon&shop_owner=xxxxxx&money_format=%24%20%7B%7Bamount%7D%7D&money_with_currency_format=%24%20%7B%7Bamount%7D%7D%20USD&province_code=&taxes_included=false&tax_shipping=&county_taxes=true&plan_display_name=affiliate&plan_name=affiliate&myshopify_domain=xxxxxx.myshopify.com&google_apps_domain=&google_apps_login_enabled=&money_in_emails_format=%24%7B%7Bamount%7D%7D&money_with_currency_in_emails_format=%24%7B%7Bamount%7D%7D%20USD&eligible_for_payments=false&requires_extra_payments_agreement=false&password_enabled=true&has_storefront=true&setup_required=false

您需要使用原始 POST 正文而不是 req.body。

尝试这样的事情:

app.post('/somepath', function (req, res, next) {
    var hmacReceived = req.headers['x-shopify-hmac-sha256'];
    hmac = crypto.createHmac('SHA256',secret);

    req.on("data", function(data) {
        hmac.update(data);
    });

    req.on("end", function() {
        var calculatedHmac = hmac.digest("base64");
        var test1 = hmacReceived === calculatedHmac;
    });

    req.on("error", function(err) {
        return next(err);
    });
}

此类似问题的更多详细信息:

HMAC MD5 Validation with Node.js, Express and Trialpay

原来是因为我没有在回调中的任何地方回复客户,例如:

res.sendStatus(200); or res.sendStatus(500); etc...

这很奇怪,因为我的回调中的代码执行得很好(即使没有回复客户端)但显然 如果节点解析器意识到有一个 req.on() 并且没有对客户端的回复,无论是在它的内部还是外部,它都会忽略 req.on(..) 这真的没有意义......要么整个事情都应该打破或 none 如果缺少对客户的回复。