我只是想构建一个自动订阅API,用于POST回令牌。我可以在Sinatra中轻松完成这项工作(从AWS渲染POST的JSON) - 似乎在Express中遇到了困难;虽然我已经尝试了1000X组合,但我确定这只是一些我不知道的愚蠢。
这是Sinatra网络服务器:
# application.rb
require 'rubygems'
require 'sinatra'
require 'json'
set :port, 8081
post '/webservice/cloudwatch' do
content_type :json
puts "Body: " + request.body.read
end
哪些日志:
- -> /webservice/cloudwatch
Body: {
"Type" : "SubscriptionConfirmation",
"MessageId" : "OMIT",
"Token" : "OMIT",
"TopicArn" : "OMIT",
"Message" : "OMIT",
"SubscribeURL" : "OMIT",
"Timestamp" : "2012-02-28T21:28:02.082Z",
"SignatureVersion" : "1",
"Signature" : "OMIT",
"SigningCertURL" : "OMIT"
}
以下是Express网络服务器:
var express, app, stache;
express = require("express"), app = express.createServer();
app.configure(function () {
app.use(express.methodOverride());
app.use(express.bodyParser());
app.use(app.router);
app.set("view options", {
layout: false
});
app.use(express.errorHandler({
dumpExceptions: true,
showStack: true
}));
});
app.post("/webservice/cloudwatch", function (request, response) {
request.accepts('application/json');
console.log("post body: " + JSON.stringify(request.params));
console.log("post body: " + JSON.stringify(request.body.read));
});
app.listen(8081);
哪些日志:
post body: []
post body: undefined
请帮忙!
答案 0 :(得分:2)
您使用哪个请求来测试您的网络服务?做:
curl -H "Content-Type: application/json" -d '{"Type":"SubscriptionConfirmation","MessageId":"OMIT","Token":"OMIT","TopicArn":"OMIT","Message":"OMIT","SubscribeURL":"OMIT","Timestamp":"2012-02-28T21:28:02.082Z","SignatureVersion":"1","Signature":"OMIT","SigningCertURL":"OMIT"}' http://localhost:8081/webservice/cloudwatch
(注意设置为application / json的内容类型)并将console.log
更改为console.log(request.body);
应该会给您预期的结果。 bodyParser方法需要知道content-type才能正确填充request.body。
答案 1 :(得分:2)
当amazon将http post请求发送到您的端点时,它不会指定内容类型。根据他们的回答,这是他们已知的问题。
与此同时,我一直在测试一个非常糟糕的解决方法。我在express插件中修改了bodyParser.js文件。具体来说,我在mime函数中添加了if检查,以便我可以根据需要强制它假装内容类型为application/json
。
这是修改后的mime函数:
function mime(req) {
if(req.headers['x-amz-sns-message-type'] == 'SubscriptionConfirmation' && !req.headers.hasOwnProperty['content-type']) {
req.headers['content-type'] = 'application/json';
}
var str = req.headers['content-type'] || '';
return str.split(';')[0];
}
答案 2 :(得分:0)
将以下内容添加到您的快速服务器(确保bodyParser位于rawbody之后)。尝试记录request.rawbody
var rawbody = function(req, res, next) {
var data = '';
req.setEncoding('utf8');
req.on('data', function(chunk) {
data += chunk;
});
req.on('end', function() {
req.rawBody = data;
next();
});
};
app.use(rawbody);
app.use(express.bodyParser());