简体   繁体   English

Rails默认使用“ text / javascript”内容类型,以响应使用form_for构建的简洁的JavaScript表单

[英]Rails Defaults to “text/javascript” Content Type in Response to Unobtrusive JavaScript Form Built With form_for

I'm using Rails 4.1.1 and Ruby 2.1.2p95. 我正在使用Rails 4.1.1和Ruby 2.1.2p95。 I am using Slim as my HTML templating language (similar to HAML). 我正在使用Slim作为我的HTML模板语言(类似于HAML)。 I'm using Thin as my Rack server. 我使用Thin作为我的机架服务器。

I am trying to make a fully-AJAX application (one of my requirements is that I may not reload the page). 我正在尝试制作一个完全AJAX的应用程序(我的要求之一是我不能重新加载页面)。

PROBLEM 问题

I have a user sign-up page that looks like this: 我有一个用户注册页面,如下所示:

= 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

I have a UsersController action that looks like this (for the purposes of this example): 我有一个如下所示的UsersController动作(出于本示例的目的):

  def create
    render html: "PRETEND A USER WAS CREATED"
  end

I have a response handler that looks like this (this is not important really - suffice to say the success handler does not fire and the error handler does): 我有一个响应处理程序,看起来像这样(这实际上并不重要-可以说成功处理程序不会触发而错误处理程序会触发):

   $("#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 sends back a response with a Content-Type header set to "text/javascript". Rails发回一个Content-Type标头设置为“ text / javascript”的响应。 Therefore the browser tries to parse the response as JavaScript, which of course fails, and causes the error event instead of the success event for the AJAX response. 因此,浏览器尝试将响应解析为JavaScript,这当然会失败,并导致错误事件而不是AJAX响应的成功事件。

SOLUTIONS THAT I DON'T LIKE 我不喜欢的解决方案

I can fix this by being explicit with Rails, either by specifying the request URL format in the form_for call: 我可以通过用Rails显式地解决此问题,方法是在form_for调用中指定请求URL格式:

= form_for( User.new, url: user_path( format: :html ), remote: true ) do |f|
  ...

or by specifying the header explicitly in the controller action: 或通过在控制器操作中显式指定标头:

def create
    render html: "PRETEND A USER WAS CREATED", content_type: :html
end

but I'm pretty upset that I even have to do this. 但我很沮丧,甚至必须这样做。 Nobody asked Rails to return a javascript response. 没有人要求Rails返回JavaScript响应。 Their own documentation says that the controller defaults to "text/html" , which is obviously true most of the time but not when using their unobtrusive javascript tools. 他们自己的文档说,控制器默认为“ text / html” ,这在大多数情况下显然是正确的,但在使用不引人注目的javascript工具时却不是这样。

I would love to understand what is going on here and if there are any ways I can configure my application so I don't need to write these extra workarounds. 我很想了解这里发生的事情,以及是否有任何方法可以配置我的应用程序,因此我不需要编写这些额外的解决方法。

Thanks in advance good people. 在此先感谢好人。

Okay I should have guessed this was partly a caching issue when I realized it was inexplicably intermittent. 好的,当我意识到这是莫名其妙的间歇性问题时,我应该猜这部分是缓存问题。 Basically, the solution is simply to force Rails to treat the request as an HTML request, but if the browser has cached the responses as JavaScript before you figure this out, it won't work until you clear the browser cache. 基本上,解决方案只是强制Rails将请求视为HTML请求,但是如果在您弄清该问题之前浏览器已经将响应作为JavaScript进行了缓存,则在您清除浏览器缓存之前它不会起作用。

I added the following code to my ApplicationController: 我将以下代码添加到我的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

These are the minimal forms, which can be made smarter for your needs (eg forcing the request format conditionally). 这些是最小的表格,可以根据您的需求使其变得更智能(例如,有条件地强制使用请求格式)。 The default_request_format_html callback is the more critical one - if you have this correct from the beginning you theoretically shouldn't need the cache-busting callback. default_request_format_html回调是更关键的回调-如果从一开始就具有正确的设置,则从理论上讲,您不需要缓存清除回调。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM