【问题标题】:How do you send JSON data in a rails-ujs Rails.ajax POST call (not using jQuery)?如何在 rails-ujs Rails.ajax POST 调用(不使用 jQuery)中发送 JSON 数据?
【发布时间】:2017-08-22 14:35:51
【问题描述】:

我有一个需要与 Rails API 对话的 React 客户端应用程序。我想使用 rails-ujs 方法 Rails.ajax。例如:

Rails.ajax({
  type: "POST", 
  url: "/things",
  data: mydata,
  success: function(response) {...},
  error: function(response) {...}
})

看起来我无法将 data 设置为这样的 JSON 对象:

mydata = {
 thing: {
  field1: value1,
  field2: value2,
}}

我需要像这样手动将其转换为 application/x-www-form-urlencoded 内容类型:

mydata = 'thing[field1]=value1&thing[field2]=value2'

这对于平面数据是可以的,但对于嵌套数据来说很快就会变得复杂。

jQuery 在发出请求之前会自动进行转换。

所以我想知道Rails UJS 是否有某种自动的方法,但我在文档或代码中找不到任何内容。

【问题讨论】:

标签: ruby-on-rails ajax ruby-on-rails-5


【解决方案1】:

使用Rails UJS时,数据必须格式化为字符串形式的参数。不幸的是,无法提供 JSON,至少目前在 Rails 6.0.2 中无法提供(不理想)。

解决方案

使用URLSearchParams 将 JSON 转换为 URL 参数:

myData = {
 thing: {
  field1: value1,
  field2: value2,
}}

Rails.ajax({
  type: "POST",
  url: "/things",
  data: new URLSearchParams(myData).toString()
})

【讨论】:

  • 我收到此错误NoMethodError (undefined method permit' for "[object Object]":String):`
  • @alexventuraio 不幸的是,您无法使用 URLSearchParams 嵌套数据
【解决方案2】:

这是我使用 Content-Type 放置/发布的解决方法:application/json。

它通过在 beforeSend 回调中设置 options.data 来工作。这样,内部 Rails.ajax.createXHR 方法不会首先设置 Content-Type 标头。 https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts/rails-ujs/utils/ajax.coffee#L53

    Rails.ajax({
      url: 'http://some-url.com',
      type: 'put',
      beforeSend(xhr, options) {
        xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8')
        // Workaround: add options.data late to avoid Content-Type header to already being set in stone
        // https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts/rails-ujs/utils/ajax.coffee#L53
        options.data = JSON.stringify(data)
        return true
      },
    });

【讨论】:

  • 在新的 rails 6 应用程序上尝试从 jquery 和 javascript 资产管道(移至 webpacker)移开时遇到问题。这是唯一有效的。我的旧 jquery 代码只使用了一个 Get 查询,无法让它工作。移到一个帖子,这工作得很好。它甚至在刺激控制器中
【解决方案3】:

我多次使用ajax调用,我曾经这样发送json数据。

var fd = new FormData();
fd.append("jsondata", JSON.stringify(mydata));

$.ajax({
  url: ...
  type :"post",
  data: fd
  success:function(){
  }
})

在 ruby​​ 控制器中解析 Json 数据很容易。 你可以使用JSON.parse(params["jsondata"])
希望这适用于您的情况。

【讨论】:

  • 这不是我想要的。不过谢谢你的回答。
【解决方案4】:

我查看了库代码,但它不支持,因为要发送对象,您必须对对象进行字符串化,然后我发现库检查数据是否为字符串类型它改变了application/x-www-form-urlencoded 的请求的内容类型。 这个link 显示了库中的情况。 为此,您解决此问题的选择是编写一个方法,将对象转换为输入表单方式或使用 JQuery Ajax 或其他库。

【讨论】:

  • 是的,你是对的,艾哈迈德。这也是我看过的那段代码。我只是想知道是否还有其他地方可以对数据进行预处理,以防我错过了。谢谢你的回答。
【解决方案5】:

不确定我是否误解了这个问题,但你不能只使用 JSON.stringify 转换你的对象吗?

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

当然,我可以在 rails-ujs 模块中看到它使用 JSON.parse 来解析 Json 响应

【讨论】:

  • 你说得对,我可以自己转换。我的问题是 rails-ujs 中是否有内置方式(如在 jQuery 中,请参阅processData)。另外,我说的是请求数据中的 JSON,而不是响应。
  • 我不这么认为,但不知道为什么这是一笔大买卖? JSON.stringify 的开销非常低。还是我不明白你想做什么?
【解决方案6】:

您可以在 ajax 调用中设置内容类型并以 json 格式发送数据

var data={
      user:{
        first_name: firstname,
        last_name: lastname,
        username: username
      }}

通过将内容类型作为 json 放在 http 标头请求中来发送 ajax 调用

$.ajax({
   type: "POST",
   url: "http://someurl/post",
   data:data,
   contentType: "application/json",
   success: function(data) {
       -------
  }
});​

【讨论】:

  • OP 没有提到 jQuery,只有 RailsUJS 库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-12
  • 2012-05-13
相关资源
最近更新 更多