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,有人有解决方法吗?

重现问题的说明

  1. 设置一个新的 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
    
  2. 使 Thing.name 成为必需的属性

    # app/models/thing.rb
    class Thing < ActiveRecord::Base
      validates :name, presence: true
    end
    
  3. 启动服务器,然后 - 在浏览器中 - 导航到 /things

  4. 尝试在不提供 name 的情况下创建新事物,Rails 将再次呈现表单并出现错误 Name can't be blank
  5. 使用浏览器刷新页面。

预期行为

浏览器应该重新提交表单(通常询问 "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

情况变得更糟

editupdate 的问题相同。假设我们有一个有效的 Thingid: 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,或者如果您碰巧没有 indexshow 视图,重新加载会导致应用抛出 "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,可以使用早期版本。