Rails:刷新无效表单页面时 Chrome 和 Firefox 中的意外行为
Rails: unexpected behaviour in Chrome and Firefox when refreshing invalid form page
当用户在提交无效表单后刷新页面时,浏览器应尝试重新提交表单。在 Chrome 和 Firefox(但不是 Safari)中,浏览器对 create/update url 执行 GET
请求。
编辑
删除 Turbolinks 解决了这个问题 - 所有浏览器都会在刷新提交的表单页面时正确调用 POST
。 Chrome 更新破坏 Turbolinks 的不是 first time,有人有解决方法吗?
重现问题的说明
设置一个新的 rails 应用程序并搭建一个名为 Thing
的测试模型
# using Ruby 2.3.1 and Rails 5.0.0
rails new testapp & cd testapp
rails generate scaffold Thing name:string
rails db:create db:migrate db:test:prepare
使 Thing.name
成为必需的属性
# app/models/thing.rb
class Thing < ActiveRecord::Base
validates :name, presence: true
end
启动服务器,然后 - 在浏览器中 - 导航到 /things
- 尝试在不提供
name
的情况下创建新事物,Rails 将再次呈现表单并出现错误 Name can't be blank
。
- 使用浏览器刷新页面。
预期行为
浏览器应该重新提交表单(通常询问 "are you sure?" 或类似的),并呈现相同的表单错误页面。
查看服务器输出,我们应该看到:
# Navigate to /things
Started GET "/things"
# Click on "New Thing"
Started GET "/things/new"
# Click on "Create Thing" without filling in "name"
Started POST "/things" # <= attempts to create, fails, renders the form with errors
# Refresh the page
Started POST "/things" # <= POST called, the form is resubmitted
实际行为
在 Chrome 和 Firefox(但不是 Safari)中,在页面刷新时浏览器发送 GET
请求到 POST
url,有效地调用 index
.
查看服务器输出,我得到:
# Navigate to /things
Started GET "/things"
# Click on "New Thing"
Started GET "/things/new"
# Click on "Create Thing" without filling in "name"
Started POST "/things" # <= attempts to create, fails, renders the form with errors
# Refresh the page
Started GET "/things" # <= expected POST
情况变得更糟
edit
和 update
的问题相同。假设我们有一个有效的 Thing
和 id: 1
保存在数据库中,这发生在 Chrome 和 Safari 中:
# Click on "Edit Thing"
Started GET "/things/1/edit"
# Delete the existing "name" and click on "Update Thing"
Started PUT "/things/1" # <= attempts to update, fails, renders the form with errors
# Refresh the page
Started GET "/things/1" # <= expected POST
如果 url 不是 RESTful,或者如果您碰巧没有 index
或 show
视图,重新加载会导致应用抛出 "No route"
错误。
帮助
有没有人遇到过这种情况?我在 Rails 回购问题中找不到任何这方面的痕迹,但也许我看错了。
我也尝试了 Ruby 2.1.2
和 Rails 4.0.4
,得到了相同的结果。
我遇到了同样的问题!终于有人遇到同样的问题了。
我认为这是因为您可能使用 turbolinks 5. 或更高版本。
将您的 turbolinks 降级到 5 之前的版本(例如:ver 2.5.3)您应该有预期的行为(浏览器重新提交表单并询问 "are you sure?" 或类似)。
使用你的 'how to replicate problem',我尝试切换 turbolink 版本几次以确保并确认这个结果。
目前,如果您不想完全删除 turbolinks,可以使用早期版本。
当用户在提交无效表单后刷新页面时,浏览器应尝试重新提交表单。在 Chrome 和 Firefox(但不是 Safari)中,浏览器对 create/update url 执行 GET
请求。
编辑
删除 Turbolinks 解决了这个问题 - 所有浏览器都会在刷新提交的表单页面时正确调用 POST
。 Chrome 更新破坏 Turbolinks 的不是 first time,有人有解决方法吗?
重现问题的说明
设置一个新的 rails 应用程序并搭建一个名为
的测试模型Thing
# using Ruby 2.3.1 and Rails 5.0.0 rails new testapp & cd testapp rails generate scaffold Thing name:string rails db:create db:migrate db:test:prepare
使
Thing.name
成为必需的属性# app/models/thing.rb class Thing < ActiveRecord::Base validates :name, presence: true end
启动服务器,然后 - 在浏览器中 - 导航到
/things
- 尝试在不提供
name
的情况下创建新事物,Rails 将再次呈现表单并出现错误Name can't be blank
。 - 使用浏览器刷新页面。
预期行为
浏览器应该重新提交表单(通常询问 "are you sure?" 或类似的),并呈现相同的表单错误页面。
查看服务器输出,我们应该看到:
# Navigate to /things
Started GET "/things"
# Click on "New Thing"
Started GET "/things/new"
# Click on "Create Thing" without filling in "name"
Started POST "/things" # <= attempts to create, fails, renders the form with errors
# Refresh the page
Started POST "/things" # <= POST called, the form is resubmitted
实际行为
在 Chrome 和 Firefox(但不是 Safari)中,在页面刷新时浏览器发送 GET
请求到 POST
url,有效地调用 index
.
查看服务器输出,我得到:
# Navigate to /things
Started GET "/things"
# Click on "New Thing"
Started GET "/things/new"
# Click on "Create Thing" without filling in "name"
Started POST "/things" # <= attempts to create, fails, renders the form with errors
# Refresh the page
Started GET "/things" # <= expected POST
情况变得更糟
edit
和 update
的问题相同。假设我们有一个有效的 Thing
和 id: 1
保存在数据库中,这发生在 Chrome 和 Safari 中:
# Click on "Edit Thing"
Started GET "/things/1/edit"
# Delete the existing "name" and click on "Update Thing"
Started PUT "/things/1" # <= attempts to update, fails, renders the form with errors
# Refresh the page
Started GET "/things/1" # <= expected POST
如果 url 不是 RESTful,或者如果您碰巧没有 index
或 show
视图,重新加载会导致应用抛出 "No route"
错误。
帮助
有没有人遇到过这种情况?我在 Rails 回购问题中找不到任何这方面的痕迹,但也许我看错了。
我也尝试了 Ruby 2.1.2
和 Rails 4.0.4
,得到了相同的结果。
我遇到了同样的问题!终于有人遇到同样的问题了。
我认为这是因为您可能使用 turbolinks 5. 或更高版本。 将您的 turbolinks 降级到 5 之前的版本(例如:ver 2.5.3)您应该有预期的行为(浏览器重新提交表单并询问 "are you sure?" 或类似)。
使用你的 'how to replicate problem',我尝试切换 turbolink 版本几次以确保并确认这个结果。
目前,如果您不想完全删除 turbolinks,可以使用早期版本。