【问题标题】:AWS SNS webservice subscription - express issue, sinatra exampleAWS SNS 网络服务订阅 - 快递问题,sinatra 示例
【发布时间】:2012-03-18 09:42:30
【问题描述】:

我只是想构建一个自动订阅 API 来回传令牌。我可以在 Sinatra 中很容易地做到这一点(从 AWS 渲染 POSTed 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

请帮忙!

【问题讨论】:

  • 不要在request.body.read 上执行console.log,而是尝试在request.body 上执行console.dir,看看它包含什么属性。
  • console.dir(request.body);这会记录 {}
  • console.dir(request.body.read);这记录未定义
  • 好的。看看Node Docs on ServerRequest objects。我不熟悉 Sinatra,但也许您正在寻找 request.headers

标签: javascript node.js amazon-web-services express amazon-sns


【解决方案1】:

当亚马逊向您的端点发送 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】:

    您使用哪个请求来测试您的网络服务?正在做:

    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。

    【讨论】:

      【解决方案3】:

      将以下内容添加到您的快速服务器(确保 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());
      

      感谢:Expressjs raw body

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-25
        • 2015-09-26
        • 1970-01-01
        • 2021-11-25
        • 2016-06-27
        • 1970-01-01
        相关资源
        最近更新 更多