让我解释一下这里发生了什么。在HTTP中,我经常会混淆客户端发送到服务器的Accept header和Content-type Header。Accept header用于告诉服务器他们将接受哪些内容类型(例如application/json、application/javascript、application/octet-stream、audio/mpeg、image/png、multipart/alternative、text/plain、text/html、text/csv、video/mpeg等)。服务器会发送一个响应,其中包括Content-Type header,通知客户端实际内容的内容类型。
HTTP请求也可以指定Content-Type,因为在表单数据中,可能有各种类型的数据,而Content-Type header可以通知服务器数据的实际类型(例如multipart/form-data)。像multipart/form-data这样的不同媒体类型称为MIME。
现在,jQuery.ajax()有另一个与此主题相关的参数:accepts、contentType、dataType。
如果你理解Content-Type HTTP header,那么contentType attribute就很清楚了。它告诉服务器数据的实际类型。在jQuery中,默认值是"application/x-www-form-urlencoded; charset=UTF-8",对于大多数情况来说都可以。
记住,Accept头告诉服务器它将接受什么Content-Type。但是当您阅读jQuery文档的dataType时,它听起来非常相似:“您期望从服务器返回的数据类型。”那么区别在哪里?
accepts属性允许您更改请求中的Accept头。但是通过更改dataType,它也会更改Accept头,因此实际上没有必要更改accept属性;dataType将更改Accept头。 dataType的好处是可以在可用于成功处理程序之前预处理响应。
实际上,我们需要告诉Rails我们将接受什么作为响应头,因此我们修改dataType。 在Rails中,例如,符号:js和:json对应于HTTP Mime Type:
Mime::Type.register "text/javascript", :js, %w( application/javascript application/x-javascript )
Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
因此,如果我们想在 respond_to 块中触发 :js 选项,那么我们需要在 jQuery 中指定 dataType 为 script。正如其中一个答案所示,您可以像这样完成它:
$.ajax({
url: "users/populate_user,
type: "POST",
data: formdata,
dataType: 'script'
});
现在看看请求头有多漂亮:
![enter image description here](https://istack.dev59.com/ymLdf.webp)
注意指定dataType为script时,Accept标头更改为application/javascript。还要注意contentType为“application/x-www-form-urlencoded; charset=UTF-8”。记住我说过,如果没有指定,则这是jQuery将使用的默认Content-Type?好吧,此SO页面中提供的另一个答案也指定了此选项:
contentType: false
根据jQuery文档:
自jQuery 1.6起,您可以传递false告诉jQuery不设置任何内容类型标头。
最后一点。在Rails控制器中,如果此控制器操作仅响应于:js,则无需指定:js标志。您可以从控制器中简单地省略respond_to:
def populate_user
@user = User.from_names(params[:name][:value]).first
end
然后添加一个名为 users/populate_user.js.erb 的文件。同时确保你的路由设置为 post 请求:
post 'users/populate_user', to: 'users#populate_user'
从Stack Overflow复制和粘贴答案时,了解你在项目中使用的内容非常重要。
dataType: 'script'
似乎完美地解决了这个问题,而不需要改变URL。 - Andrew K