Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Browse files

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...
1 parent e17e08e commit 123eb25fd12c5a5ec63e18082dcdda6318bc942e @wycats wycats committed
1  actionpack/lib/action_dispatch.rb
@@ -47,6 +47,7 @@ module ActionDispatch
autoload_under 'middleware' do
+ autoload :BestStandardsSupport
autoload :Callbacks
autoload :Cookies
autoload :Flash
3  actionpack/lib/action_dispatch/railtie.rb
@@ -7,10 +7,11 @@ class Railtie < Rails::Railtie
config.action_dispatch.x_sendfile_header = ""
config.action_dispatch.ip_spoofing_check = true
config.action_dispatch.show_exceptions = true
+ config.action_dispatch.best_standards_support = true
# Prepare dispatcher callbacks and run 'prepare' callbacks
initializer "action_dispatch.prepare_dispatcher" do |app|
ActionDispatch::Callbacks.to_prepare { app.routes_reloader.execute_if_updated }
1  railties/lib/rails/application.rb
@@ -205,6 +205,7 @@ def default_middleware_stack
middleware.use ::ActionDispatch::ParamsParser
middleware.use ::Rack::MethodOverride
middleware.use ::ActionDispatch::Head
+ middleware.use ::ActionDispatch::BestStandardsSupport if config.action_dispatch.best_standards_support
2  railties/lib/rails/commands.rb
@@ -70,4 +70,4 @@
All commands can be run with -h for more information.
2  railties/lib/rails/engine/configuration.rb
@@ -50,4 +50,4 @@ def autoload_paths
1  railties/test/application/routing_test.rb
@@ -40,6 +40,7 @@ def index
get '/foo'
assert_equal 'foo', last_response.body
+ assert_equal "IE=Edge,chrome=1", last_response.headers["X-UA-Compatible"]
test "simple controller with helper" do

28 comments on commit 123eb25


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


Strange seeing something IE-specific to go in Rails.


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.


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? ;-)


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


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


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.


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.


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?

script/plugin install git://

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


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


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.


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').


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.


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.


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.


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.


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?


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


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.


@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.


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


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".


"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.


"off in development mode" -1

The rule of least surprise.


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.


@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.