问题
I'm in the process of rebuilding a PHP app in Node.js on top of the Express framework.
One part of the application is a callback url that an Amazon SNS notification is posted to.
The POST body from SNS is currently read in the following way in PHP (which works):
$notification = json_decode(file_get_contents('php://input'));
In Express I have tried the following:
app.post('/notification/url', function(req, res) {
console.log(req.body);
});
However, watching the console, this only logs the following when the post is made:
{}
So, to repeat the question: How do you access an Amazon SNS post body with Express / Node.js
回答1:
Another approach would be to fix the Content-Type header.
Here is middleware code to do this:
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();
};
}
This assumes there is a file called util.js located in the root project directory with:
util = require('./util');
in your app.js and invoked by including:
app.use(util.overrideContentType());
BEFORE
app.use(express.bodyParser());
in the app.js file. This allows bodyParser() to parse the body properly...
Less intrusive and you can then access req.body normally.
回答2:
This is based on AlexGad's answer.Particularly this comment:
The standard express parser will only handle application/json, application/x-www-form-encoded and multipart/form-data. I added some code above to place before your 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('') )
})
})
回答3:
Take a look at AWS Node.js SDK - it can access all AWS service endpoints.
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
}
});
EDIT: The problem is that the standard body parser does not handle plain/text which is what SNS sends as the content type. Here is code to extract the raw body. Place it before your body parser:
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();
});
});
You can then use:
JSON.stringify(req.rawBody));
within your route to create a javascript object and operate on the SNS post appropriately.
You could also modify the body parser to handle text/plain but its not a great idea to modify middleware. Just use the code above.
来源:https://stackoverflow.com/questions/18484775/how-do-you-access-an-amazon-sns-post-body-with-express-node-js