[英]Why is respond_to executing format.html instead of format.json when using AJAX?
I've been looking for similar topics but although I've read a lot I'm still a bit confused about the respond_to block usage.我一直在寻找类似的主题,但虽然我读了很多书,但我仍然对 respond_to 块的使用感到有些困惑。
I'm doing an AJAX request by using form_with in the client side.我正在通过在客户端使用 form_with 来执行 AJAX 请求。 In the controller, my action looks like this:
在 controller 中,我的操作如下所示:
def create
@role = Role.new(role_params)
respond_to do |format|
if @role.save
format.html { redirect_to url_for(controller: 'roles', action: 'index') }
format.json { render json: { :location => url_for(controller: 'roles', action: 'index') }, status: 302 }
else
format.html { render action: 'new' }
format.json { render json: { :errors => @role.errors }, status: 422 }
end
end
end
The way I understand respond_to bock is that when you make an AJAX request it should answer back by using json, and If you make a regular request it should answer back by using html.我理解 respond_to bock 的方式是,当您发出 AJAX 请求时,它应该使用 json 回复,如果您发出常规请求,它应该使用 html 回复。 Is that correct?
那是对的吗?
In this case, it always answers back by using format.html.在这种情况下,它总是使用 format.html 进行回复。 I've checked that If I put format.json first (above format.html) It indeed answer back by using json.
我已经检查过,如果我先放 format.json(在 format.html 上方),它确实通过使用 json 回复。
What's wrong or what am I missing?有什么问题或我错过了什么?
Thanks!谢谢!
form_with
by default sends XHR (ajax)
request requiring you to have a java-script template
for the response and then use format.js
inside the respond method. form_with
默认发送XHR (ajax)
请求,要求您有一个用于响应的java-script template
,然后在响应方法中使用format.js
。
however if you want to make a json
or any other request formats such as xml
you can pass the format as a parameter to the path helper method like this:但是,如果您想制作
json
或任何其他请求格式,例如xml
,您可以将格式作为参数传递给路径辅助方法,如下所示:
admin_roles_path(format: :json)
or use the format option directly in the form_with
call but since you are already using the url
option the format
option will be omitted.或直接在
form_with
调用中使用格式选项,但由于您已经在使用url
选项, format
选项将被省略。
for more information this is a good post to read.有关更多信息, 这是一篇很好的文章。
The way I understand respond_to bock is that when you make an AJAX request it should answer back by using json, and If you make a regular request it should answer back by using html.
我理解 respond_to bock 的方式是,当您发出 AJAX 请求时,它应该使用 json 回复,如果您发出常规请求,它应该使用 html 回复。 Is that correct?
那是对的吗?
Not quite.不完全的。 An AJAX request is just an asynchronous request and the response type should depend on the Content-Type and Accept-Type headers.
AJAX 请求只是一个异步请求,响应类型应取决于 Content-Type 和 Accept-Type 标头。 An AJAX request request can actually request any possible content type - JSON is just the most commonly used and arguably the most useful type.
AJAX 请求请求实际上可以请求任何可能的内容类型 - JSON 只是最常用的并且可以说是最有用的类型。
If the request does not contain a specific content type or accept type Rails will default to html unless you override it in the routes:如果请求不包含特定的内容类型或接受类型,Rails 将默认为 html,除非您在路由中覆盖它:
namespace :api, defaults: { format: :json } do
namespace :v1 do
resources :things
end
end
Rails UJS which is built into rails and powers the remote: true
option on forms and links actually uses application/javascript
as the default content-type as it lets you write js.erb
views and reuse rails templating without writing ajax handlers. Rails UJS 内置在 rails 中并为
remote: true
选项和链接实际上使用application/javascript
作为默认内容类型,因为它允许您编写js.erb
视图并重用 rails 模板,而无需编写 ajax 处理程序。 If this is really a good idea though is debatable as it leads to some very questionable design decisions.如果这真的是一个好主意,虽然是有争议的,因为它会导致一些非常有问题的设计决策。
With Rails UJS the easiest way to set the content type is through the data-type
attribute:使用 Rails UJS 设置内容类型的最简单方法是通过
data-type
属性:
<%= link_to "Click Me!", "/foo", remote: true, data: { type: :json } %>
<%= form_with(model, html: { data: { type: "json" }}) %>
If you are sending an Ajax request "manually" with XMLHttpRequest you can set the content type with setRequestHeader
.如果您使用 XMLHttpRequest “手动”发送 Ajax 请求,则可以使用
setRequestHeader
设置内容类型。
xhr.setRequestHeader("Content-Type", "application/json");
With jQuery you use the type:
option for the ajax funtions or jQuery.getJSON
.使用 jQuery,您可以使用
type:
选项用于 ajax 功能或jQuery.getJSON
。
Also the correct way to respond is to a successful POST request is with 201 Created.此外,正确的响应方式是使用 201 Created 来响应成功的 POST 请求。
201 Created.
201 已创建。 The request has been fulfilled and has resulted in one or more new resources being created.
请求已被满足并导致创建一个或多个新资源。 The primary resource created by the request is identified by either a Location header field in the response or, if no Location field is received, by the effective request URI.
请求创建的主要资源由响应中的 Location header 字段标识,如果没有收到 Location 字段,则由有效请求 URI 标识。
format.json { head :created, location: @role }
You can also optionally include the created resource in the response body.您还可以选择在响应正文中包含创建的资源。
format.json { render json: @role, location: @role, status: :created }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.