Skip to content
This repository
Browse code

Add a header that tells Internet Explorer (all versions) to use the b…

…est available standards support. This ensures that IE doesn't go into quirks mode because it has been blacklisted by too many users pressing the incompatible button. It also tells IE to use the ChromeFrame renderer, if the user has installed the plugin.

This guarantees that the best available standards support will be used on the client.
  • Loading branch information...
commit 123eb25fd12c5a5ec63e18082dcdda6318bc942e 1 parent e17e08e
Yehuda Katz authored July 27, 2010
1  actionpack/lib/action_dispatch.rb
@@ -47,6 +47,7 @@ module ActionDispatch
47 47
   end
48 48
 
49 49
   autoload_under 'middleware' do
  50
+    autoload :BestStandardsSupport
50 51
     autoload :Callbacks
51 52
     autoload :Cookies
52 53
     autoload :Flash
3  actionpack/lib/action_dispatch/railtie.rb
@@ -7,10 +7,11 @@ class Railtie < Rails::Railtie
7 7
     config.action_dispatch.x_sendfile_header = ""
8 8
     config.action_dispatch.ip_spoofing_check = true
9 9
     config.action_dispatch.show_exceptions = true
  10
+    config.action_dispatch.best_standards_support = true
10 11
 
11 12
     # Prepare dispatcher callbacks and run 'prepare' callbacks
12 13
     initializer "action_dispatch.prepare_dispatcher" do |app|
13 14
       ActionDispatch::Callbacks.to_prepare { app.routes_reloader.execute_if_updated }
14 15
     end
15 16
   end
16  
-end
  17
+end
1  railties/lib/rails/application.rb
@@ -205,6 +205,7 @@ def default_middleware_stack
205 205
         middleware.use ::ActionDispatch::ParamsParser
206 206
         middleware.use ::Rack::MethodOverride
207 207
         middleware.use ::ActionDispatch::Head
  208
+        middleware.use ::ActionDispatch::BestStandardsSupport if config.action_dispatch.best_standards_support
208 209
       end
209 210
     end
210 211
 
2  railties/lib/rails/commands.rb
@@ -70,4 +70,4 @@
70 70
 
71 71
 All commands can be run with -h for more information.
72 72
   EOT
73  
-end
  73
+end
2  railties/lib/rails/engine/configuration.rb
@@ -50,4 +50,4 @@ def autoload_paths
50 50
       end
51 51
     end
52 52
   end
53  
-end
  53
+end
1  railties/test/application/routing_test.rb
@@ -40,6 +40,7 @@ def index
40 40
 
41 41
       get '/foo'
42 42
       assert_equal 'foo', last_response.body
  43
+      assert_equal "IE=Edge,chrome=1", last_response.headers["X-UA-Compatible"]
43 44
     end
44 45
 
45 46
     test "simple controller with helper" do

28 notes on commit 123eb25

Yehuda Katz
Owner

Note that this can be turned off with config.action_dispatch.best_standards_support = false

Mislav Marohnić

Strange seeing something IE-specific to go in Rails.

Joel Junström

Agreeing with Mislav here, even tho it's is possible to override it with the config, seeing rails sending IE specific headers by default is in my book not what a framework should do. Is the incompatible button really a proven problem for websites? And in that case knowing how to avoid it by sending specific headers should really be in the concern of the application author(s). For those unlucky people that rely on quirks mode / forcing older rendering engines for legacy reasons this might lead to confusion. And for the rest of us just use a decent doctype, say doctype html.

Piotr Sarnacki
Collaborator

I don't think it's a bad move. Why should Rails not help with IE weirdness?

When javascript helpers were provided by Rails would you also want to handle any IE cases by yourself? ;-)

Damien Mathieu
Collaborator

I agree with drogus. Seeing something specific to IE here seems fine to me.

Wijnand Wiersma

I prefer a helper tag that inserts the equivalent metatag for IE < 9

Mislav Marohnić

Re: JavaScript frameworks: Prototype and jQuery are separate projects which are developed and released independently.

I don't claim this is a bad move, it just feels weird to me and I wanted to know what others think. As long as the preference is put into new apps by the generator, with a comment on what it does and how to turn it off, it's fine by me. Client-side magic should, if necessary, at least make itself apparent to the developer.

Tomasz Mazur

This is cool, but I think it should be turned off by default. I wouldn't call ChromeFrame "best practice". I don't know any non-dev person that install such addons to IE.

Falk Pauser

To me it feels 'bloaty' to have ie-specific stuff in rails-core. Could'nt this be a plugable rack-filter or a rails-plugin?

Joshua Peek
Collaborator
josh commented on 123eb25 July 28, 2010
script/plugin install git://github.com/rails/ie_standards.git
Tom Cocca

Josh, is that a private repo? I don't seem to have access to it. Or is that just a thought?

Damien Mathieu
Collaborator

@tcocca that was a suggestion. This repo does not exists (yet?)

David FRANCOIS

A plugin sounds much better in my opinion.
Or at least something disabled by default with a commented-out line in the template configuration file to enable it.

Falk Pauser

I think the '_snowman'-hack should also go into this 'ie_standards' plugin. The plugin would document all these ie-specific things in detail so no one should be surprised by strange ie-specific headers or a '_snowman'-param (aka 'Principle of Least Surprise').

Nate Wiger

Agree with josh and mislav - putting IE hacks into Rails is the opposite direction it has been moving. If Rails is going to have IE hacks in core, then browser-independent functionality like pagination and ssl_requirement should move back into core. Plugin please.

Yehuda Katz
Owner

There are actually quite a few hacks already in Rails for Internet Explorer. I think most users expect Rails to make Internet Explorer behave as expected, without having to understand the problems that give rise to the issues in question, as long as we don't resort to sniffing IE in particular.

IE hacks already in Rails:

  • Rails modifies original_filename on uploaded file objects to hack around a bug where Internet Explorer was giving full Windows file paths
  • Files sent via send_file set Content-Type to application/octet-stream to work around quirks in IE involving SSL
  • Files sent via send_file set Cache-Control to "private" because the default "no-cache" broke the open/save dialog
  • HTTP authentication handles a case in IE where the URL sent in the Authorization header is absolute (containing http:// etc)

We also handle (by default) a quirk in some versions of Safari in which it sends a trailing null character at the end of params, and another in which it does not correctly handle an empty body (so we send " " for render :text => :none)

Rails has always handled weird Internet Explorer quirks, because (like when using a JavaScript library), Rails users don't even want to know that these problems exist. If they had to wait until the first time a user reported a bug with a file download, research it, and find the Rails plugin that patched the cache headers, they would be (correctly) quite frustrated.

Again, the line that I personally draw is that we don't fix any user-agent bugs that absolutely require sniffing. Otherwise, making the vast majority of both Rails developers and users of applications written in Rails blissfully unaware of Internet Explorer quirks is what we're here for.

Alex Russell

nateware, mislav: So this isn't so much a "hack" as the supported way in IE to trigger a given rendering mode which, thanks to history, is orthogonal from doctype depending on the zone...a change in behavior you almost never want. All this change does is set a designer up for success by setting things into the most standards compliant mode available regardless of zone. As for Chrome Frame, I can tell you with some authority that many users are installing it and the rate is increasing, but I'm biased as I work on the project. That said, on many Google properties, Chrome Frame is providing orders of magnitude improvements in performance over IE and is allowing apps to send better (more standards compliant even than IE8) code.

Rick Martínez

I disagree with this being called a "hack." It's just a header that sets a new preferred expectation for IE dealing with Rails applications. I think it's extremely beneficial as a default and too easy to turn off by those who would actually not want this functionality.

Xac Stegner
Xac commented on 123eb25 July 28, 2010

Could this confuse developers that are testing in IE with chrome frame installed (but don't know it's active)? I'm not very familiar with CF but I assume if you need to send a header to use it if it's installed, it wouldn't be used by default during normal page loading. Will future Rails developers doing cross browser testing need to know to manually disable this if they want to test with IE's default rendering engine?

Yehuda Katz
Owner

@xac good point. We should have this off in development mode by default :)

Mislav Marohnić

I never called this a "hack"—others did. These are nothing more than mere parameters that trigger certain features in IE.

@wycats: What you summarized is all HTTP-level, and we all know that Rails gracefully abstracts away its details (and quirks) from the developer. This change is a little different because it affects the rendering side of a browser. But I generally agree with arguments in defense of this change, and with Xac in his point against.

Mitchell Hashimoto

@wycats Discussing this with a coworker, we think this would be a good idea to add to the test mode as well, for those who run continuous integration builds which run selenium clients against the various browsers. Of course in these environments chrome frame probably shouldn't be installed, but it would be a good default to disable it in test mode, I believe.

Rick Martínez

"We should have this off in development mode by default" +1

Paul Irish

IE Compatibility mode can kick in for a few reasons:

  1. Sites that run inside an intranet (except localhost and the loopback address)
  2. Users that have opted-in to the Compatibility View List and your site incorrectly flagged
  3. Users that have clicked the broken-page icon accidentally (directly next to Refresh and Stop). it affects the whole domain.
  4. Some other content on the site caused IE8/9's renderer to crash and fall back to the old renderer;
  5. A user or group policy setting made all sites to be viewed in compat mode.

In all cases, the user will get the Trident equivalent of IE7 (but the JScript version of IE8 or IE9) -- For example localStorage is present in IE8 Compat Mode, but you still get the CSS bugs of IE7. These pseudo- browser versions are likely to be edge case bugs QA wouldn't normally catch.

The X-UA-Compatible header forces the latest mode, resulting in the best possible experience for the user, using the fastest (and best) rendering engine available. As Steve Souders likes to recommend, it's "fast by default".

Wijnand Wiersma

"off in development mode" -1

When I am going through the hell of fixing IE rendering bugs I am working in development mode. I want pages to look exactly the same when in production.
I don't want to add a IE hack to find out it creates another bug in production.

Jason Weathered

"off in development mode" -1

The rule of least surprise.

dlee
dlee commented on 123eb25 July 28, 2010

I agree with Wijnand that rendering should be consistent between development and production.

A developer would expect rails to trigger ChromeFrame when installed, and non-quirks-mode otherwise. We don't want a developer to be confused because IE6 is not using ChromeFrame in development even though it's installed. We also don't want IE6 using quirks mode in development but non-quirks-mode in production.

Rick Martínez

@dlee, that's a good point. I was thinking only of triggering ChromeFrame. With chrome=1 I think it more sense until you hit an issue where the developer is doing some IE specific magic via a user-agent check that doesn't account for ChromeFrame and it gets triggered when it shouldn't. Regarding IE=edge, I agree that behavior should not differ between dev and production.

Please sign in to comment.
Something went wrong with that request. Please try again.