Rails中form_for/form_tag设remote:true仍以HTML提交问题排查
我之前在维护Rails 3项目时也碰到过一模一样的问题,结合Rails 3基于jQuery UJS的AJAX机制,给你梳理几个最可能的原因和排查方向:
确认jQuery与jquery_ujs的加载顺序和完整性
Rails 3的AJAX表单完全依赖jquery_ujs插件,而这个插件必须在jQuery加载完成后才能正常初始化。检查你的app/assets/javascripts/application.js文件,确保包含以下两行,且顺序绝对不能颠倒://= require jquery //= require jquery_ujs要是漏了其中任意一行,或者把
jquery_ujs放在jQuery前面,UJS的表单绑定逻辑就会直接失效,表单会默认走HTML提交流程。检查页面是否存在JavaScript报错
打开浏览器开发者工具的Console面板(按F12切换),看看页面加载或点击提交按钮时有没有抛出错误。比如$ is not defined说明jQuery根本没加载成功,或者其他语法错误阻断了后续代码执行——只要有未捕获的JS错误,UJS的绑定逻辑就会被中断,自然无法触发AJAX提交。排查自定义JS是否干扰了表单提交事件
如果你在页面里写了自定义的表单submit事件处理函数,比如:$('form').submit(function() { // 一些自定义业务逻辑 return false; });这种写法会直接阻止浏览器的默认提交行为,同时也会打断UJS的AJAX处理流程。正确的做法要么是在自定义逻辑里手动实现AJAX提交,要么确保函数最后
return true,或者避免直接覆盖submit事件(改用on('click', 'submit', ...)这种更温和的绑定方式)。检查表单是否存在嵌套结构
HTML规范明确禁止表单嵌套,Rails的UJS也无法正确解析嵌套的表单DOM。如果你的form_for/form_tag被包裹在另一个<form>标签里,浏览器会解析出错误的DOM结构,导致UJS无法正确绑定到目标表单上。确认表单是否包含文件上传字段
Rails 3的jquery_ujs不支持通过AJAX提交包含<input type="file">的表单(当时FormData API还没被主流浏览器广泛支持)。如果你的表单里有文件上传控件,哪怕设置了remote: true,UJS也会自动降级为HTML提交。这种情况你需要借助第三方插件(比如jquery-fileupload)来实现AJAX文件上传。验证表单的HTML属性是否正确生成
查看页面源码,确认目标表单的HTML标签里是否存在data-remote="true"属性。如果没有,说明你的form_for/form_tag的remote: true参数没有生效——检查一下参数写法是否正确(比如有没有拼写错误,写成remot: true),或者是否被其他选项(比如:html选项)覆盖了remote属性。检查是否全局禁用了UJS
有些项目会因为特殊需求全局禁用UJS,比如在代码里写了$.rails.enable = false;,这会直接关闭所有UJS功能,包括AJAX表单提交。你可以在浏览器控制台里输入$.rails.enable,看看返回值是不是true。
内容的提问来源于stack exchange,提问作者alikk

