2013-08-28 24 views
10

我正在重建Node.js中的PHP应用程序,并在Express框架之上。如何使用Express/Node.js访问Amazon SNS邮件正文

应用程序的一部分是Amazon SNS notification过帐的回调URL。

从SNS的POST体目前在PHP(工作)阅读下面的方法:

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

在表达我曾尝试以下:

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

然而,看着控制台,这个帖子只会记录以下内容:

{} 

因此,重复任务ion:您如何使用Express/Node.js访问Amazon SNS邮件正文

+0

作为上下文:这种(合理的,天真的)方法失败的原因是SNS HTTP设置。 “Content-Type:text/plain; charset = UTF-8” 请参阅:http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.html (SNS并不真正讨好JSON) – Jason

回答

22

另一种方法是固定的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正常。

+2

这是一个很好的答案,特别是如果您想使用同一个应用来处理来自SNS的通知和订阅确认。 – supaseca

+0

http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.html#SendMessageToHttp.prepare AWS使用'text/plain'作为Content-Type是否有原因?处理这件事真是令人头疼。很高兴在那里有一个解决方案 – lasec0203

+0

看看[这个主题](https://forums.aws.amazon.com/thread.jspa?threadID=69413)并得出你自己的结论。注意日期。与其试图寻找替代方法来解决问题,不如解决它。 – Talma

3

看看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运营后适当。

您也可以修改body parser来处理text/plain,但修改中间件不是一个好主意。只需使用上面的代码。

+0

我认为这可能是更早的阶段。我的申请已经订阅。 SNS会发布到它,因为我可以在控制台中看到它,但我无法访问该帖子的正文。 – timstermatic

+1

啊,明白了,对不起。我现在明白你在做什么。我相信即使文本是JSON格式,SNS也会以text/plain的形式发送内容。你如何设置你的身体解析器?标准表达式解析器只能处理application/json,application/x-www-form-encoded和multipart/form-data。我在上面添加了一些代码,放在你的body parser之前。它会给你一个你的请求中的rawbody,你可以测试,以确保你从SNS获取数据。记录下来,然后你可能必须编写你自己的身体分析器。 – AlexGad

+0

我无法得到这个工作。然而,它确实指出了我对req.on和chunking的正确方向,所以感谢您的意见。我已经把我的解决方案作为接受的答案。 – timstermatic

5

这是基于AlexGad的answer.Particularly此评论:

标准快递解析器将只处理应用程序/ JSON,应用程序/ x-WWW的形式编码和多/表单数据。我在上面添加了一些代码,放在你的body parser之前。

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('')) 
    }) 
}) 
+0

技术上正确的是,较高的投票数是指定问题的“更清洁”解决方案。让经过良好测试的框架完成这项工作... – andreas

相关问题