Rails默认为"text/javascript"响应使用form_for构建的非显眼JavaScr
Rails Defaults to "text/javascript" Content Type in Response to Unobtrusive JavaScript Form Built With form_for
我使用Rails 4.1.1和Ruby 2.1.2p95。我使用Slim作为我的HTML模板语言(类似于HAML)。我使用Thin作为我的机架服务器。
我正在尝试制作一个全ajax应用程序(我的要求之一是我可能不会重新加载页面)。
我有一个用户注册页面,看起来像这样:
= form_for( User.new, url: user_path, remote: true ) do |f|
= f.label :username
= f.text_field :username, label: true
= f.label :password
= f.password_field :password, label: true
= f.label :password_confirmation
= f.password_field :password_confirmation, label: true
= f.submit
我有一个UsersController动作,看起来像这样(为了这个例子的目的):
def create
render html: "PRETEND A USER WAS CREATED"
end
我有一个响应处理程序,看起来像这样(这真的不重要-足以说明成功处理程序不触发,错误处理程序):
$("#dynamic_body").on( "ajax:success", "[data-remote]", function( event, data, status, xhr ) {
$("#dynamic_body").empty();
$("#dynamic_body").append( data );
});
$("#dynamic_body").on( "ajax:error", "[data-remote]", function( event, xhr, status, error ) {
$("#dynamic_body").empty();
$("#dynamic_body").append( error );
});
Rails返回一个带有Content-Type报头设置为"text/javascript"的响应。因此,浏览器试图将响应解析为JavaScript,这当然会失败,并导致错误事件而不是AJAX响应的成功事件。
我不喜欢的解决方案
我可以通过显式使用Rails来解决这个问题,或者通过在form_for调用中指定请求URL格式:
= form_for( User.new, url: user_path( format: :html ), remote: true ) do |f|
...
或者通过在控制器动作中显式指定标头:
def create
render html: "PRETEND A USER WAS CREATED", content_type: :html
end
但我很不高兴,我甚至不得不这样做。没有人要求Rails返回javascript响应。他们自己的文档说控制器默认为"text/html",这在大多数情况下显然是正确的,但在使用他们不引人注目的javascript工具时就不是这样了。
我很想知道这里发生了什么,如果有任何方法可以配置我的应用程序,这样我就不需要编写这些额外的变通方法。
提前感谢好心人。
好吧,当我意识到它莫名其妙地断断续续时,我应该猜到这部分是缓存问题。基本上,解决方案只是强制Rails将请求视为HTML请求,但如果在您弄清楚之前浏览器已将响应缓存为JavaScript,则在清除浏览器缓存之前它将无法工作。
我添加了以下代码到我的ApplicationController:
class ApplicationController < ActionController::Base
...
# These two filters together should ensure we return HTML responses to the browser's AJAX reqeusts.
before_filter :prevent_caching
before_filter :default_request_format_html
...
private
...
def prevent_caching
expires_now
end
def default_request_format_html
request.format = "html"
end
end
这些是最小的表单,可以根据你的需要更智能(例如,有条件地强制请求格式)。default_request_format_html
回调是更关键的一个-如果你从一开始就正确地使用它,理论上你不应该需要缓存破坏回调。
- 我应该如何从xml文件构建一个javascript页面
- 如何在DOM元素上按类型构建此函数
- 铬:“;未捕获的语法错误:意外的标记:"
- Sencha Touch构建-排除文件
- RubyonRails——构建交互式接口应该朝哪个方向发展
- 可以设置“;文件名"发生错误时显示的内联脚本标记的
- JS表单提交"无法使用Chrome数据保护程序加载此页面.尝试重新加载页面.调试信息:POST CISmtuK
- 检测电话窃听,即:<a href="电话:xxx">在UIWebview上
- 使用“+="操作人员
- //而不是在src=“”上使用http://"属性
- "未捕获的语法错误:意外的标记}"
- 可以<脚本类型=“;text/javascript”>window.location=“/"</
- "实例范围”;TypeScript类的getter/setter
- Javascript复选框函数:;缺少:在属性id之后"
- "npm运行构建:css"不能工作,而当我自己运行脚本时是可以的
- 我正在使用php includes来构建一个多页面网站.使用jquery,我将如何添加一个类"活动的”;添加到
- "npm运行构建“;模块解析错误”;您可能需要一个适当的加载程序来处理此文件类型&”;
- 构建一个2d html5画布游戏,并尝试用javascript连接到服务器以创建播放器"高芯&”;
- "用“;在Scala中从JavaScript构建
- "构建“;JS变量