Rails 7移动端联系表单失效问题求助
问题描述
跟着教程开发第一个Ruby on Rails项目,已部署到生产环境。PC端浏览器的联系表单可正常发送邮件,但移动端浏览器点击发送按钮仅刷新页面,表单输入内容保留。相关代码及日志如下:
HTML代码
<%= form_for(@contact, :html => { :class => "form-stacked"}, :remote => true) do |f| %> <form class="contact__form"> <h3 class="text-md ">Contact Us</h3> <p class="mb-5">Reach out to the world’s most reliable services.</p> <div class="input-group"> <%= f.text_field :name, required: true, class: 'input', placeholder: "Your name"%></br> </div> <div class="input-group"> <%= f.text_field :Email, required: true, class: 'input', placeholder: "Email Address"%></br> </div> <div class="input-group-2 mb-4"> <%= f.text_area :message, required: true, class: 'input', rows: "4", placeholder: "Your Message"%></br> </div> <%= f.submit 'Send Message', class: 'btn btn-main' %> <% end %>
Controller代码
class ContactsController < ApplicationController skip_before_action :verify_authenticity_token def new @contact = Contact.new end def create @contact = Contact.new(params[:contact]) @contact.request = request if @contact.deliver flash.now[:success] = 'Message sent!' else flash.now[:error] = 'Could not send message' render :new end end end
PC端发送日志
[55fef2dc-48af-448a-9af1-5d63774682c6] Started POST "/contacts" for 172.71.102.128 at 2023-01-17 12:46:11 +0000 [55fef2dc-48af-448a-9af1-5d63774682c6] Processing by ContactsController#create as HTML [55fef2dc-48af-448a-9af1-5d63774682c6] Parameters: {"contact"=>{"name"=>"siri", "Email"=>"user@gmail.com", "message"=>"piytan"}, "commit"=>"Send Message"} [55fef2dc-48af-448a-9af1-5d63774682c6] Rendered /layers/heroku_ruby/gems/vendor/bundle/ruby/3.1.0/gems/mail_form-1.9.0/lib/mail_form/views/mail_form/contact.erb (Duration: 1.7ms | Allocations: 834)[2023-01-17T12:46:11.726778 #1] INFO -- : [55fef2dc-48af-448a-9af1-5d63774682c6] Delivered mail 63c6989313cac_1a3482043b@asi4her-588fcb97b9-c8d2m.mail (646.5ms) [55fef2dc-48af-448a-9af1-5d63774682c6] Rendered contacts/create.html.erb within layouts/application (Duration: 0.9ms | Allocations: 179) [55fef2dc-48af-448a-9af1-5d63774682c6] Rendered layout layouts/application.html.erb (Duration: 3.2ms | Allocations: 1186) [55fef2dc-48af-448a-9af1-5d63774682c6] Completed 200 OK in 671ms (Views: 3.7ms | ActiveRecord: 0.0ms | Allocations: 7819)
移动端发送日志
[f272778b-c913-49f1-b407-e1c8b4288798] Started POST "/contacts" for 172.71.182.191 at 2023-01-17 12:45:53 +0000 [f272778b-c913-49f1-b407-e1c8b4288798] Processing by ContactsController#create as HTML [f272778b-c913-49f1-b407-e1c8b4288798] Parameters: {"contact"=>{"name"=>"siri", "Email"=>"User@gmail.com ", "message"=>"Hii"}, "commit"=>"Send Message"} [f272778b-c913-49f1-b407-e1c8b4288798] Rendered contacts/new.html.erb within layouts/application (Duration: 1.3ms | Allocations: 929) [f272778b-c913-49f1-b407-e1c8b4288798] Rendered layout layouts/application.html.erb (Duration: 3.6ms | Allocations: 1899) [f272778b-c913-49f1-b407-e1c8b4288798] Completed 200 OK in 5ms (Views: 4.3ms | ActiveRecord: 0.0ms | Allocations: 2148)
问题分析与解决方案
核心问题
对比两端日志可知:PC端执行了邮件发送流程并渲染create视图,而移动端直接渲染了new视图,说明@contact.deliver验证失败,触发了render :new分支,导致页面刷新且表单内容保留。具体原因有三点:
嵌套form标签违反HTML规范
form_for已经生成了完整的form标签,代码中又嵌套了<form class="contact__form">,HTML不允许form嵌套。移动端浏览器对这种无效结构的解析逻辑与PC端不同,可能导致AJAX提交(remote: true)失效,或参数传递异常。字段名大小写不匹配
表单中邮箱字段用了:Email(大写E),但MailForm模型的邮箱属性应为:email(小写),大小写不匹配会导致参数无法正确映射到模型属性,触发邮箱格式验证失败。邮箱参数含末尾空格
移动端提交的邮箱参数末尾带有空格,不符合邮箱格式规则,直接导致deliver方法验证失败。
修复步骤
- 移除嵌套form标签,合并class属性
将内层<form class="contact__form">删除,把class加到form_for的html选项中:
<%= form_for(@contact, html: { class: "form-stacked contact__form" }, remote: true) do |f| %> <!-- 原表单内容 --> <% end %>
- 修正邮箱字段名为小写
把:Email改为:email,确保与模型属性一致:
<%= f.text_field :email, required: true, class: 'input', placeholder: "Email Address" %><br>
- 处理参数中的空格
在Controller中对提交的参数做trim处理,避免首尾空格导致验证失败:
def create contact_params = params[:contact].transform_values(&:strip) @contact = Contact.new(contact_params) @contact.request = request if @contact.deliver flash.now[:success] = 'Message sent!' else flash.now[:error] = 'Could not send message' render :new end end
- 确保AJAX依赖正常加载
检查项目布局文件,确认已引入Rails的UJS脚本(Rails 6+为@rails/ujs),保证remote: true的AJAX提交能正常运行:
<!-- Rails 5及以下 --> <%= javascript_include_tag 'application' %> <!-- Rails 6+ --> <%= javascript_pack_tag 'application' %>
完成以上修改后,移动端表单可正常触发邮件发送,不会出现刷新页面且内容保留的问题。
内容的提问来源于stack exchange,提问作者user21005264
相关产品推荐
相关产品推荐

