使用DELETE而不是GET进行Rails删除后重定向

22

我有一个路由,我正在发出 DELETE 请求:

user_authorization_path(@user, authorization)

它很好地击中了我的控制器,控制器删除了资源,然后发出重定向:

redirect_to edit_user_path(params[:user_id])

结果是重定向时出现路由错误:

ActionController::RoutingError (No route matches [DELETE] "/users/1/edit")

我可以在日志中看到Rails直到重定向之前都做得很对,但问题在于它试图发出另一个DELETE而不是GET请求:

我能看到日志显示Rails在重定向前的行为都是正确的,但重定向时它尝试发出一个DELETE请求而不是GET请求:

Started DELETE "/users/1/authorizations/12"...
...
Redirected to http://localhost:3000/users/1/edit
Completed 302 Found in 8ms (ActiveRecord: 0.2ms)

Started DELETE "/users/1/edit"...

ActionController::RoutingError (No route matches [DELETE] "/users/1/edit")

Chrome 调试器显示了初始请求:

Request URL:http://localhost:3000/users/1/authorizations/12
Request Method:DELETE
Status Code:302 Found

接着重定向:

Request URL:http://localhost:3000/users/1/edit
Request Method:GET
Status Code:404 Not Found

看起来浏览器正确地跟随了重定向,但Rails忽略了重定向调用上的GET,而是使用DELETE,导致出现404(因为该资源不支持DELETE - 这本身就是错误的)。

如果我只是在重定向后的URL上执行'GET',那么它可以正常运行。

我对Rails的删除后重定向漏掉了什么?谢谢。

1个回答

31

以下方法可以更好地解决问题:

redirect_to edit_user_path(params[:user_id]), status: 303

http://api.rubyonrails.org/classes/ActionController/Redirecting.html

如果您在使用除GET或POST之外的XHR请求并在请求后重定向,则某些浏览器将使用原始请求方法跟随重定向。 这可能会导致不良行为,例如重复删除。为了解决这个问题,可以返回303 See Other状态码,该状态码将使用GET请求进行跟踪。


比更改路由好多了。至少有人读文档。谢谢! - carlosvini
3
你可以使用 :see_other 替代 :303。我认为这样更易读。 - Michał Zalewski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接