我有一个路径http://www.example.com/confirm_post/12
,它向posts#confirm_post
提交了一个帖子请求。当用户成功从该路径提交表单时,是否有办法阻止用户再次访问相同的路径(可能是来自浏览器后退按钮或用户手动点击URL)?
答案 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
,因为我们正在更新资源 - 而不是创建新资源。