如何在Rails中向jquery-ujs的post请求追加数据?

9
我有一个带有data-remote="true"属性的Ajax表单,我正在将其提交到Rails中的控制器。
我想要做的是使用jquery-ujs事件系统在将请求发送到服务器之前附加数据。
类似于这样:
$("#my_form").bind('ajax:beforeSend', function(xhr, settings){
  // serialize some object and append it
});

我无法弄清如何对数据进行标记?

编辑 这是控制台中“xhr”对象的样子。

f.Event
currentTarget: DOMWindow
data: undefined
exclusive: undefined
handleObj: Object
handler: function N(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;i<s.length;i++)g=s[i],g.origType.replace(y,"")===a.type?q.push(g.selector):s.splice(i--,1);e=f(a.target).closest(q,a.currentTarget);for(j=0,k=e.length;j<k;j++){m=e[j];for(i=0;i<s.length;i++){g=s[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,d=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,d=f(a.relatedTarget).closest(g.selector)[0],d&&f.contains(h,d)&&(d=h);(!d||d!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){e=p[j];if(c&&e.level>c)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}
jQuery16103879226385615766: true
liveFired: HTMLDocument
namespace: ""
namespace_re: /(^|\.)(\.|$)/
result: undefined
target: HTMLFormElement
timeStamp: 1306788242911
type: "ajax:beforeSend"
__proto__: Object

你正在使用哪个版本的jQuery? - Alex Weber
看起来你的POST是空的。 - Alex Weber
应该在 data 中,对吧?不过表单运行得很完美,我可以看到数据已经通过 XMLHttpRequest 发送到了开发工具的网络选项卡中。我不明白。 - David Tuite
你尝试过将“data”设置为某些内容,例如:“foo=bar”,并检查是否已提交吗? - Alex Weber
是的,我试过了。我设置了 xhr.data = 'foo' 然后在服务器上记录了请求参数。但它没有被列出来。它似乎也没有影响到其他请求参数。这肯定是我掌握的 jqXHR 对象吗? - David Tuite
3个回答

18

最终我自己解决了这个问题。事实上,尽管文档中所说,ajax:beforeSend钩子实际上有三个参数。根据这篇有帮助的博客文章,它们按顺序是eventxhrsettings

我要找的表单数据在settings参数的data属性中。

因此,基本上,我现在可以使用该函数向请求添加数据了。

$("#my_form").bind('ajax:beforeSend', function(event, xhr, settings){
  settings.data += "&serialized=data";
});

额外的参数将在服务器上可用。


2
在Firebug中,我看到null&url=http://www.google.com,但在服务器端我没有看到那个参数:{"user_id"=>"13"} - lulalala
@lulalala 我也看到了同样的事情。当我 console.log(settings) 时,我看到 **data: "null&customize=TEST"**,customize参数没有保留。我正在使用 .on("ajax:beforeSend", "#link", function(e,xhr,settings){ settings.data += "&customize=TEST" } - Joel Grannas
如果没有添加数据,null是默认值,你可以编写 settings.data = "serialized=data",但这样可能不起作用。请使用 settings.url += '&dog=cat' - GEkk
这可能已经有所不同,因为这是旧的,但文档确实提到了使用jQuery时第一个参数将是事件对象。https://github.com/rails/jquery-ujs/wiki/ajax#important - ifightcrime

1
自从jQuery 1.5版以来,有一个本地的 beforeSend 回调函数可以绑定到您的请求上。文档链接和另一个 文档链接 编辑: 请求数据可以在jqXHR对象中获得,在beforeSend回调函数的第一个参数中。
beforeSend(jqXHR, settings)

尝试在Firebug中检查jqXHR对象,以查看它确切地存储POST数据的位置,并附加您的值。


好的,我的问题中已经有了这个(迂回地需要使用Ruby on Rails),但是我该如何将数据实际附加到请求中呢? - David Tuite
我添加了XHR对象的日志。正如您所看到的,data属性是undefined。我是否选择了正确的对象? - David Tuite

1

如果要在 beforeSend 方法(Jquery 原生方法)中更改 data 属性(至少现在,使用 Jquery 1.7.2),您只需修改 this.data 变量即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接