我有一个带有 remote: true
的表单,如下所示:
<%= form_with model: @transfer, scope: :transfer, url: transfers_path, method: 'post', remote: true do |f| %>
我的 Controller create
操作如下所示:
def create
@transfer = @account.transfers.build(transfer_params)
respond_to do |format|
if @transfer.save
format.html { redirect_to transfers_path }
else
format.js
end
end
end
如果我提交了一个没有错误的表单,页面会像预期的那样重定向。但是,我注意到服务器响应状态代码为 200,而不是 302。我的服务器日志如下所示:
Started POST "/transfers" for ::1 at 2019-06-04 08:32:22 -0700
Processing by TransfersController#create as JS
...
Redirected to http://localhost:3000/transfers
Completed 200 OK in 1476ms (ActiveRecord: 81.2ms)
Started GET "/transfers" for ::1 at 2019-06-04 08:32:23 -0700
Processing by TransfersController#index as HTML
只是想知道为什么它是 200 而不是 302?我还意识到这永远不会奏效,因为我不应该能够使用 AJAX 请求进行重定向(如果我理解正确,remote: true
会发送 AJAX 请求)。
关于 SO 的其他问题的答案似乎表明 redirect_to
不起作用,我必须使用 JS 来设置重定向的窗口位置。一些示例答案:
- > https://stackoverflow.com/a/23433009/3504731
- > https://stackoverflow.com/a/37601358/3504731
- > https://stackoverflow.com/a/16098942/3504731
我对为什么我的代码能正常工作感到困惑。任何人都可以对此有所了解吗?我怀疑 rails-ujs
在幕后做一些魔术,但我不确定。具体来说,我怀疑these lines但我不太擅长 JS,我无法解析其中的大部分内容。我也在运行 Rails 5.2.1。
最佳答案
首先,form_with
不使用remote
,它使用local
并且设置为false
默认情况下,就像 form_for
和 remote: true
一样。
其次,respond_to
并不像您认为的那样有效。您不选择响应格式,而是由客户选择。
如果客户端发送常规 HTTP 请求 (remote: false
),则您的 create
会在 format.html
之后响应该 block 。如果客户端发送 AJAX 请求 (remote: true
),则 create
会使用 format.js
部分进行响应。
没有重定向,因为 format.html { redirect_to transfers_path }
在您发出 AJAX 请求后从未运行。
在浏览器开发工具的网络选项卡中检查响应,以了解实际情况。
另外,重构你的方法:
def create
@transfer = @account.transfers.build(transfer_params)
saved = @transfer.save
respond_to do |format|
format.html do
if saved
redirect_to transfers_path
else
flash.now[:notice] = 'Error'
render :new
end
end
format.js # Create app/views/<controller>/create.js.erb and
# update page there
end
end
关于javascript - 具有 'remote: true' 的表单即使使用重定向也会返回 200 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56447279/