【问题标题】:jQuery JSON post to a Sinatra route not working correctlyjQuery JSON 发布到 Sinatra 路由无法正常工作
【发布时间】:2013-07-30 05:54:35
【问题描述】:

我有一条如下所示的 Sinatra 路线:

post '/participants/create' do
  puts request.body.read
end

我正在使用 jQuery POST 来实现它:

javascript:
  $('#contact').on('submit',function () {
    $.ajax({
      url: 'participants/create',
      dataType: 'json',
      contentType: 'application/json',
      type: 'POST',
      data : JSON.stringify({ name: "Dom"}),
      success: function(json) {
        alert('all done');
      }
    })
  })

无论出于何种原因,正文始终为空,并且 request.content-type 始终为application/x-www-form-urlencoded。很困惑。

【问题讨论】:

  • 您是否阻止了表单提交?
  • 嗯……好问题。我需要使用 preventDefaults 不是吗?
  • 在处理程序的主体中尝试p params。 Sinatra 有时会做一些奇怪的参数处理。
  • Dominic,试试function(event) {...event.preventDefault()。此外,Sinatra 可以为您将 POST 数据放入 params 对象/助手中,无需阅读请求正文。也看看jquery-json,我听说过它的好消息。最后,尝试使用halt 200, params.inspect 而不是puts 回复...。

标签: ajax json sinatra


【解决方案1】:

我忘了一点,因为我想把所有东西都塞进 cmets 所以我就回答一下。

post '/participants/create', :provides => :json do
  # I'd use a 201 as the status if actually creating something,
  # 200 while testing.
  # I'd send the JSON back as a confirmation too, hence the
  # :provides => :json
  data = JSON.parse params
  # do something with the data, then…
  halt 200, data.to_json
  # halt because there's no need to render anything
  # and it's convenient for setting the status too
end


javascript:
  $('#contact').on('submit',function (event) {
    event.preventDefault();
    $.ajax({
      url: 'participants/create',
      dataType: 'json',
      contentType: 'application/json',
      type: 'POST',
      data : JSON.stringify({ name: "Dom"}),
      accepts: "application/json",
      success: function(json) {
        alert(json);
      }
    })
  })

但总的来说,为什么要将 JSON 发送到 HTTP 服务器?我发现最好将 HTTP 发送到服务器,将 JSON 发送到 javascript,因为这是他们都更喜欢的方式。 YMMV。

post '/participants/create', :provides => :json do
  # Do something with the params, then…
  halt 200, params.to_json 
end

javascript:
  $('#contact').on('submit',function (event) {
    event.preventDefault();
    $.ajax({
      url: 'participants/create',
      dataType: 'json',
      type: 'POST',
      data : { name: "Dom"}, // or $(event.target).serialize()
      accepts: "application/json",
      success: function(json) {
        alert(json);
      }
    })
  })

【讨论】:

  • 谢谢。对问题进行了排序,但是关于 JSON 到 HTTP 服务器的要点。
  • @DominicBou-Samra 很高兴听到你把它整理好了。
  • 嗯,我对第二个答案有点困惑。您是说将 HTTP 发送到 Sinatra,然后将 JSON 发送到浏览器?为什么不对两者都使用 JSON?另外.. 在这两个例子中,params 都是空的,但是 request.body.read 有数据。
  • @DominicBou-Samra 问题应该是,为什么要在服务器上增加一个从 JSON 解析数据的额外转换步骤? Sinatra(和其他 HTTP 应用程序服务器/框架)可以很好地处理 HTTP POST,而无需使用 JSON。然而,Javascript 可以很好地与 JSON,because it maps nicely to its object model 一起使用,并且库中对它有很多支持。我让它工作了,这里有一个 repo 可以查看github.com/yb66/stackoverflow-q-17870680
  • 在这种情况下,#participants/create 方法需要能够接受来自许多来源的输入(不仅仅是网络表单)。也许我应该让它同时响应 HTTP 和 JSON。
猜你喜欢
  • 2016-11-26
  • 2014-12-05
  • 2018-01-17
  • 2017-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多