19

我正在Express框架之上在 Node.js 中重建 PHP 应用程序。

应用程序的一部分是一个回调 URL,Amazon SNS 通知发布到该 URL。

来自 SNS 的 POST 正文当前在 PHP 中以以下方式读取(有效):

$notification = json_decode(file_get_contents('php://input'));

在 Express 中,我尝试了以下方法:

app.post('/notification/url', function(req, res) {
    console.log(req.body);
});

但是,查看控制台,这只会在发布帖子时记录以下内容:

{}

所以,重复这个问题:如何使用 Express / Node.js 访问 Amazon SNS 帖子正文

4

4 回答 4

42

另一种方法是修复Content-Type标头。

这是执行此操作的中间件代码:

exports.overrideContentType = function(){
  return function(req, res, next) {
    if (req.headers['x-amz-sns-message-type']) {
        req.headers['content-type'] = 'application/json;charset=UTF-8';
    }
    next();
  };
}

这假设在根项目目录中有一个名为util.js的文件,其中包含:

util = require('./util');

在您的app.js中并通过以下方式调用:

app.use(util.overrideContentType());

app.use(express.bodyParser());

app.js文件中。这允许 bodyParser() 正确解析正文...

侵入性较小,然后您可以正常访问req.body

于 2014-04-04T19:19:16.290 回答
5

这是基于 AlexGad 的回答。特别是这个评论:

标准的 express 解析器只会处理 application/json、application/x-www-form-encoded 和 multipart/form-data。我在上面添加了一些代码放在您的正文解析器之前。

app.post('/notification/url', function(req, res) {
    var bodyarr = []
    req.on('data', function(chunk){
      bodyarr.push(chunk);
    })  
    req.on('end', function(){
      console.log( bodyarr.join('') )
    })  
})
于 2013-08-28T19:14:42.770 回答
4

看看AWS Node.js SDK - 它可以访问所有 AWS 服务端点。

    var sns = new AWS.SNS();

    // subscribe
    sns.subscribe({topic: "topic", Protocol: "https"}, function (err, data) {
      if (err) {
        console.log(err); // an error occurred
      } else {
        console.log(data); // successful response - the body should be in the data
     }
   });


    // publish example
    sns.publish({topic: "topic", message: "my message"}, function (err, data) {
      if (err) {
        console.log(err); // an error occurred
      } else {
        console.log(data); // successful response - the body should be in the data
     }
   });

编辑:问题是标准正文解析器不处理纯文本/文本,这是 SNS 作为内容类型发送的内容。这是提取原始主体的代码。把它放在你的身体解析器之前:

app.use(function(req, res, next) {
    var d= '';
    req.setEncoding('utf8');
    req.on('d', function(chunk) { 
        d+= chunk;
    });
    req.on('end', function() {
        req.rawBody = d;
        next();
    });
});

然后你可以使用:

JSON.stringify(req.rawBody));

在您的路线中创建一个 javascript 对象并适当地对 SNS 帖子进行操作。

您还可以修改正文解析器以处理文本/纯文本,但修改中间件不是一个好主意。只需使用上面的代码。

于 2013-08-28T13:28:30.900 回答
1

假设您正在使用 body-parser,您可以这样做。

只需将以下行添加到您的 app.js 中:

app.use(bodyParser.json());
app.use(bodyParser.text({ type: 'text/plain' }));

这个信息也可以在body-parser官方文档中找到:
https ://github.com/expressjs/body-parser

于 2020-04-14T18:39:51.537 回答