如何阻止表单再次从特定URL重新提交

时间:2018-04-16 10:32:53

标签: ruby-on-rails ruby

我有一个路径http://www.example.com/confirm_post/12,它向posts#confirm_post提交了一个帖子请求。当用户成功从该路径提交表单时,是否有办法阻止用户再次访问相同的路径(可能是来自浏览器后退按钮或用户手动点击URL)?

1 个答案:

答案 0 :(得分:1)

  

当用户成功从该路径提交表单时,是否有办法   阻止用户再次访问相同的路径(它可能来自   浏览器后退按钮或用户手动点击网址??

浏览器不会平等对待POST和GET请求。 POST请求是非幂等的,因此如果您尝试备份,浏览器在大多数情况下会实际警告您。

但是,您实际上无法阻止浏览器重新发送任何请求,但这通常只需在控制器中添加简单条件或模型验证(如唯一性验证)即可。您的控制器必须能够处理重复或未经授权的请求并返回响应而不会产生意外的副作用。

在这种情况下,我会这样处理:

resources :posts do
  patch :confirm
end
      Prefix Verb   URI Pattern                       Controller#Action
post_confirm PATCH  /posts/:post_id/confirm(.:format) posts#confirm
...
# on the edit or show view
<% unless @post.confirmed? %>
  <%= button_to("Confirm", post_confirm_path(@post), method: :patch) %>
<% end %>
class PostsController < ApplicationController
  # ...
  # PATCH /posts/:post_id
  def confirm
    @post = Post.find(params[:post_id])
    if @post.confirmed?
      # we return since we want to bail early
      redirect_to @post, error: "Post already confirmed." and return
    end
    if @post.update(confirmed: true) 
      redirect_to @post, success: "Post confirmed." 
    else
      redirect_to @post, error: "Post could not be confirmed"
    end 
  end
  # ...
end

请注意,这会使用PATCH HTTP谓词而不是POST,因为我们正在更新资源 - 而不是创建新资源。