Dav*_*ite 34 jquery ruby-on-rails ruby-on-rails-3
我有一个标准的控制器,它被设置为响应HTML,JS和JSON请求:
def picture
@picture = Picture.new params[:picture]
respond_to do |format|
if @picture.save
format.html do
logger.debug "In the HTML responder"
redirect_to @picture
end
format.json { render json: @picture, status: :created, location: @picture }
format.js { render :nothing => true }
else
# you get the idea
end
end
end
Run Code Online (Sandbox Code Playgroud)
现在我正在尝试使用该$.ajax
函数向该控制器发送请求(我不能:remote => true
在这种特定情况下使用 - 我正在尝试使ajax文件上传工作).
$.ajax({
url: $("form#new_picture").attr("action"),
type: "POST",
data: formdata,
processData: false,
contentType: false
});
Run Code Online (Sandbox Code Playgroud)
问题是我的请求由于某种原因被视为HTML请求.如何告诉rails我想要JS响应?
顺便说一句,我在我的项目中使用了jquery_ujs,所以如果有必要,我可以访问它提供的方法.我不是很擅长JS来调整那里做我需要的东西.
nde*_*eau 52
这个解决方案对我不起作用(rails 3.1 + coffeescript).在搜索了很多之后,我找到了做这件事的好方法,我想分享:
只需将".js"添加到网址的末尾即可.很简单... ;-)
shl*_*sky 31
只需添加 dataType: 'script'
$.ajax({
url: $("form#new_picture").attr("action"),
type: "POST",
data: formdata,
processData: false,
contentType: false,
dataType: 'script'
});
Run Code Online (Sandbox Code Playgroud)
您必须在发送ajax请求之前设置'accept'标头,以便Rails知道如何响应.
$.ajax({
url: $("form#new_picture").attr("action"),
type: "POST",
data: formdata,
processData: false,
contentType: false,
beforeSend: function(xhr, settings) {
xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
}
});
Run Code Online (Sandbox Code Playgroud)
让我解释一下这里发生了什么。
我经常在 HTTP 中混淆客户端发送到服务器的 Accept 标头和 Content-type 标头。Accept 标头用于告诉服务器什么内容类型(application/json、application/javascript、application/octet-stream、audio/mpeg、image/png、multipart/alternative、text/plain、text/html、text/csv 、视频/mpeg 等)他们会接受。服务器发回一个响应,其中包括 Content-Type 标头,通知客户端内容的实际内容类型。
HTTP 请求也可以指定 Content-Type,因为在表单数据中,可以有所有类型的数据,而 Content-Type 头可以通知服务器数据实际上是什么(例如 multipart/form-data)。不同的媒体类型如 multipart/form-data 被称为 MIME。
现在 jQuery.ajax() 有另一个你可以传递给它的与这个主题相关的参数:accepts、contentType、dataType。
如果您了解 Content-Type HTTP 标头,则 contentType 属性很清楚。它告诉服务器数据实际上是什么。jQuery 中的默认值是“application/x-www-form-urlencoded; charset=UTF-8”,这在大多数情况下都可以。
请记住,Accept 标头告诉服务器它将接受什么 Content-Type。但是当您阅读有关 dataType 的 jQuery 文档时,它听起来非常相似:“您期望从服务器返回的数据类型。” 那么区别是什么呢?
accepts 属性允许您更改请求中的 Accept 标头。但是通过改变 dataType 也会改变 Accept 头,所以真的没有必要改变 accept 属性;dataType 将更改 Accept 标头。dataType 的好处是 ti 允许您在可用于成功处理程序之前预处理响应。
实际上,我们需要告诉 Rails 我们将接受什么作为响应头,因此我们修改了 dataType。例如,在 Rails 中,符号 :js 和 :json 对应于 HTTP Mime 类型:
Mime::Type.register "text/javascript", :js, %w( application/javascript application/x-javascript )
Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
Run Code Online (Sandbox Code Playgroud)
因此,如果我们想触发 respond_to 块中的 :js 选项,那么我们需要在 jQuery 中将 dataType 指定为脚本。正如其中一个答案所说明的那样,您可以这样做:
$.ajax({
url: "users/populate_user,
type: "POST",
data: formdata,
dataType: 'script'
});
Run Code Online (Sandbox Code Playgroud)
现在看看 Request Header 看起来有多漂亮:
请注意如何将 dataType 指定为脚本将 Accept 标头更改为 application/javascript。还要注意 contentType 是“application/x-www-form-urlencoded; charset=UTF-8”。还记得我说过如果没有指定,这是 jQuery 将使用的默认 Content-Type 吗?这个 SO 页面中提供的另一个答案也指定了这个选项:
contentType: false
Run Code Online (Sandbox Code Playgroud)
根据 jQuery 文档:
从 jQuery 1.6 开始,您可以传递 false 来告诉 jQuery 不要设置任何内容类型标头。
最后一点。在您的 Rails 控制器中,如果此控制器操作只会响应 :js,则您不需要指定 :js 标志。您可以简单地从控制器中省略 respond_to :
def populate_user
@user = User.from_names(params[:name][:value]).first
end
Run Code Online (Sandbox Code Playgroud)
然后添加一个 users/populate_user.js.erb 文件。还要确保为发布请求设置了路由:
post 'users/populate_user', to: 'users#populate_user'
Run Code Online (Sandbox Code Playgroud)
从 SO 复制和粘贴答案时,准确了解您在项目中使用的内容也很重要。
添加dataType: 'script'
和表格数据添加如下参数format: 'js'
:
$.ajax({
url: '/manager/consumers/url',
type: 'GET',
dataType: 'script',
data: {
authenticity_token: '<%= form_authenticity_token %>',
param_1: '1',
param_2: '2',
format: 'js'
}
});
Run Code Online (Sandbox Code Playgroud)
还添加控制器以不渲染布局:
respond_to do |format|
format.xls
format.js { render :layout => false }
end
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
24139 次 |
最近记录: |