Rails使用remote: true在Safari提交表单失败的解决办法
解决Rails remote: true表单在Safari中无法提交的问题
我之前也碰到过类似的Safari兼容性问题,结合你提供的代码和错误信息,给你几个针对性的解决思路,尽量保留Rails原生工具的使用:
1. 显式设置表单的multipart属性
虽然form_with在包含file_field时会自动添加multipart: true,但Safari对这个属性的识别有时候会有偏差,建议显式指定:
= form_with(model: Request.new, class: 'g-form g-contact__form', id: 'form', remote: true, multipart: true) do |f| = f.file_field :attachments, class: 'g-input__field-file', multiple: true = f.submit '袨褌锌褉邪胁懈褌褜', class: 'g-btn g-btn_submit', id: 'form_submit', data: { "disable-with": "袨褌锌褉邪胁谢褟械屑..." }
2. 调整控制器的响应头和内容类型
Safari对AJAX响应的头部要求比Chrome/Firefox严格,尤其是文件上传场景下,建议在respond_to块中明确指定内容类型,并添加缓存控制头避免连接异常:
def create allow_send = true @request = Request.new(request_params) if allow_send respond_to do |format| if @request.save format.js { headers['Cache-Control'] = 'no-cache, no-store' content_type 'text/javascript' RequestMailer.notify_admin(@request).deliver_now } else format.js { headers['Cache-Control'] = 'no-cache, no-store' content_type 'text/javascript' render partial: 'fail' } end end else @request.errors.add(:bot, "袣 褋芯卸邪谢械薪懈褞, 褍 薪邪褋 锌芯写芯蟹褉械薪懈械, 褔褌芯 胁褘 斜芯褌. 袩芯锌褉芯斜褍泄褌械 蟹邪锌芯谢薪懈褌褜 褎芯褉屑褍 械褖褢 褉邪蟹.") respond_to do |format| format.js { headers['Cache-Control'] = 'no-cache, no-store' content_type 'text/javascript' render partial: 'fail' } format.html end end end
3. 确保JS响应的完整性
你提到的“Network connection lost”错误,很多时候是因为Safari认为响应未正确结束。检查你的create.js.rb是否有语法错误(比如中文符号、未闭合的代码),可以尝试添加一个简单的结束标记:
$('#form-popup').toggle(); $('#success-popup').toggle(); // 确保响应完整,避免Safari判定连接中断 console.log('Form submission completed');
另外,在开发环境中,记得开启Safari的“禁用缓存”选项(Web Inspector -> 存储 -> 勾选“禁用缓存”),避免旧的响应缓存干扰测试。
4. 升级Rails UJS版本
旧版本的rails-ujs存在Safari兼容性问题,尤其是针对文件上传的AJAX处理。检查你的Gemfile,确保使用的是最新的稳定版Rails:
# Gemfile gem 'rails', '~> 7.0' # 替换为当前最新稳定版
5. 手动触发UJS提交事件(备选)
如果以上方法都无效,可以尝试手动触发UJS的提交逻辑,绕过Safari的默认表单提交行为:
document.getElementById('form').addEventListener('submit', function(e) { e.preventDefault(); // 调用Rails UJS的提交方法 Rails.fire(this, 'submit'); });
验证步骤
每次修改后,记得:
- 清空Safari的缓存和Cookie
- 使用Web Inspector的“网络”标签,查看请求的详细信息:是否发送成功、响应状态码、Content-Type是否正确、FormData是否包含所有字段
内容的提问来源于stack exchange,提问作者mohnstrudel
相关产品推荐
相关产品推荐

