如何在rails-ujs Rails.ajax POST调用中发送JSON数据(不使用jQuery)?

Hri*_*tal 10 ajax ruby-on-rails ruby-on-rails-5

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

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

看起来我不能data像这样设置JSON对象:

mydata = {
 thing: {
  field1: value1,
  field2: value2,
}}
Run Code Online (Sandbox Code Playgroud)

我需要application/x-www-form-urlencoded手动将其转换为内容类型,如下所示:

mydata = 'thing[field1]=value1&thing[field2]=value2'
Run Code Online (Sandbox Code Playgroud)

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

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

所以我想知道Rails UJS是否有一些自动方式,但我在文档或代码中找不到任何东西.

Jer*_*nch 13

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

解决方案

使用URLSearchParams以JSON转换为URL PARAMATERS:

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

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


art*_*tgb 6

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

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

$.ajax({
  url: ...
  type :"post",
  data: fd
  success:function(){
  }
})
Run Code Online (Sandbox Code Playgroud)

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


小智 6

这是我使用 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
      },
    });
Run Code Online (Sandbox Code Playgroud)