IE7 not calling formatted action properly.

This is completely bizarre. I have a respond_to block that looks kinda
like this:

    respond_to do |format|
      format.html { render :template => 'home/index' }
      format.jpg { render :template => 'admin/products/small.flexi' }
      format.xml { render :xml => @product.to_xml }
    end

Which works great in Firefox and Safari. In IE7, however, ultimate
weirdness. if I click a link from another page to this action (no file
format extension) it trigger the .jpg format code. If I refresh, it
then trigger the .html code like I expect it to.

I've never had cross browser issues like this that manifest on the
server side. Has anyone else ever seen this? Is this a bug IE7?

I'm on Rails 2.0.2, and if there is some bug fix in rails about this
that is in 2.1 maybe its worth the time to upgrade.

Anyone with hints?

Alex Wayne wrote:

This is completely bizarre. I have a respond_to block that looks kinda
like this:

    respond_to do |format|
      format.html { render :template => 'home/index' }
      format.jpg { render :template => 'admin/products/small.flexi' }
      format.xml { render :xml => @product.to_xml }
    end

Which works great in Firefox and Safari. In IE7, however, ultimate
weirdness. if I click a link from another page to this action (no file
format extension) it trigger the .jpg format code. If I refresh, it
then trigger the .html code like I expect it to.

I've never had cross browser issues like this that manifest on the
server side. Has anyone else ever seen this? Is this a bug IE7?

I'm on Rails 2.0.2, and if there is some bug fix in rails about this
that is in 2.1 maybe its worth the time to upgrade.

Anyone with hints?

A little further investigation, leads to some differences in the accept
header:

Firefox sends:
  "HTTP_ACCEPT"=>"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"

IE7 sends:
  "HTTP_ACCEPT"=>"*/*"

Could this be the culprit? Perhaps I need to declare a default format
somewhere?

Alex Wayne wrote:

A little further investigation, leads to some differences in the accept
header:

Firefox sends:
  "HTTP_ACCEPT"=>"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"

IE7 sends:
  "HTTP_ACCEPT"=>"*/*"

Could this be the culprit? Perhaps I need to declare a default format
somewhere?

I think I figured this out. IE7 is a tricky bastard. Basically, it
sends different accept headers when clicking on links, and direct
address bar access, than it does when refreshing.

Firefox's accept header lists "text/html" first, and this tells rails to
trigger the "format.html" part of the respond to block.

IE7, on the other hand, sends an HTTP_ACCEPT header like so when you
click a link:

  "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
application/x-shockwave-flash, application/ag-plugin, */*"

So rails looks at my respond_to block, and looks at that header. it
looks for a gif responder, an x-bitmap responder, and then a jpg
responder, which I do have. Rails declares is a match and sends it out.
Normally people don't generate images via a respond_to block, which is
why this hasn't come up much. Sadly, my app does this, and its actually
a pretty clean solution.

So thing that made this such a nightmare to track down was when I
refreshed the HTTP_ACCEPT header turned into simply "*/*", allowed rails
to pick the default, which was html.

The solution is a gloabl before filter, that after some trial and error,
looks like this:

    def set_default_format
      bad_accept_header = "image/gif, image/x-xbitmap, image/jpeg,
image/pjpeg, application/x-shockwave-flash, application/ag-plugin, */*"

      if request.headers['User-Agent'] =~ /MSIE/ &&
request.headers['HTTP_ACCEPT'] == bad_accept_header
        request.format = Mime::Type.lookup_by_extension(:all)
      end
    end

This forces it to behave if that funky header gets shoved to rails.
Hope this helps someone.

Once again, IE has caused me hours of pain, when all other browsers
performed flawlessly. Grumble... humbug... grrr...

Alex Wayne wrote:

Alex Wayne wrote:

A little further investigation, leads to some differences in the accept
header:

Firefox sends:
  "HTTP_ACCEPT"=>"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"

IE7 sends:
  "HTTP_ACCEPT"=>"*/*"

Could this be the culprit? Perhaps I need to declare a default format
somewhere?

I think I figured this out. IE7 is a tricky bastard. Basically, it
sends different accept headers when clicking on links, and direct
address bar access, than it does when refreshing.

Some final documentation and revelation about this is on my blog

http://beautifulpixel.com/2008/7/20/ie7-header-issues

Hopefully it helps someone from this noodle scratching problem.

I'm having a similar problem in IE 7. I have a search form that
submits to an action that can handle either AJAX or HTML requests.
Here is my respond_to block

respond_to do |format|
  format.js { render :partial => 'list_table' }
  format.html { render :action => 'index' }
end

For some reason, IE is triggering the .js format and I'm getting the
file download dialog. I did some testing, and it looks like if I swap
the order of the formats so that .html comes before .js, then IE
renders correctly.

respond_to do |format|
  format.html { render :action => 'index' }
  format.js { render :partial => 'list_table' }
end

Seems like whatever format comes first gets matched. Stupid IE.

After switching the order of the formats my AJAX calls still work, as
well as my HTML calls. Very odd.

deadwards wrote:

Seems like whatever format comes first gets matched. Stupid IE.

Right.

The only accept header item sent by IE that matches any of those formats
is */*, which means send me anything. So Rails picks the first one it
finds.

So you can either put html first, like you did, or you can add the
snippet in my linked blog post to force the html format unless a
params[:format] is explicitly declared on the url.

You just saved me a boatload of work and frustration.

Thanks

Brian Ploetz wrote:

This seems to be promoting URLs that are not "cool"
(http://www.w3.org/Provider/Style/URI) by requiring the format (.html,
.xml, etc) as an extension. That kind of stinks......

Thats good news. Obviously, HTTP clients cant yet be trusted to provide
proper headers. So relying on them is problematic. I personally like
the typed urls because it makes it super easy to grab things in a
variety of formats without any complicated header trickery. I can do it
right in my browser.

Alex Wayne wrote:

Thats good news. Obviously, HTTP clients cant yet be trusted to provide
proper headers. So relying on them is problematic. I personally like
the typed urls because it makes it super easy to grab things in a
variety of formats without any complicated header trickery. I can do it
right in my browser.

Right. It just means that I have to go through all of my views and
refactor my plain old link_to calls to look like:

link_to 'Foo', formatted_foo_url(@foo, "html")

Which is more than a pain in the arse....your filter works well until I
can get around to doing this I suppose.

Cheers.
BP

Brian Ploetz wrote:

your filter works well until I can get around to doing this I suppose.

Actually, your filter is problematic for AJAX actions which do a render
:partial => 'blah'

I've tweaked it to this, which seems to do the trick:

  def set_default_format
    if !request.xhr?
      params[:format] ||= 'html'
    end
  end

This works well for my particular set up, as most of my AJAX actions
render partials, so if you're doing something like format.js and using
RJS, you might need to tweak further.