32
votes

header("Content-type: text/css"); works in Firefox, Chrome and other, but not in Internet Explorer 9. I am not sure what's up.

In Chrome and Firework it shows the style sheet if I open it in its own tab and it's being applied to the page.

In Chrome under Network in the developer tools it says the type is text/css and the status is 200.

In Internet Explorer 9, it wants to download the style sheet if I open it in its own tab and it's not being applied to the page.

In the F12 developer tools you can click on network, start capturing and refresh the page. It shows the Style.css.php. The type is text/html and the result is 406.

This is in the head:

<link rel="stylesheet" type="text/css" href="/assets/css/style.css.php" media="screen" />

Request headers:

Key Value
Request GET /assets/css/main.css HTTP/1.1
Accept  text/css
Referer http://10.0.1.5/
Accept-Language en-US
User-Agent  Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding gzip, deflate
Host    10.0.1.5
Connection  Keep-Alive
Cookie  PHPSESSID=*Hidden*

Response headers:

Key Value
Response    HTTP/1.1 406 Not Acceptable
Date    Fri, 01 Apr 2011 10:12:42 GMT
Server  Apache/2.2.14 (Ubuntu)
Alternates  {"main.css.php" 1 {type application/x-httpd-php}}
Vary    negotiate
TCN list
Keep-Alive  timeout=15, max=100
Connection  Keep-Alive
Content-Type    text/html; charset=iso-8859-1
8
What do you mean "doesn't work"? What's the problem?Jonah
It does not load it right, its like no css file is being loaded at all in IE. If i go to the file, it wants to download it and not display it like Chrome and Firefox.Keverw
Did you try to NOT-send the header? :)Mārtiņš Briedis
yeah. The css file is a php file because i check account settings for colors of the toolbar you want.Keverw
Have you tried [Ctrl]+[F5] (forced reload)?Czechnology

8 Answers

41
votes

IE has "No, I'm not kidding about Content-Type" switch:

X-Content-Type-Options: nosniff

BTW: make sure you also send Last-Modified and disable session.cache_limiter in PHP, otherwise browsers will keep reloading the CSS file, which will negatively impact performance.

16
votes

Internet Explorer has a history of trusting the file extension over the MIME type reported by the browser. If you have mod_rewrite available, have your HTML look for a .css file and then create a mod_rewrite rule that pipes that URL to your script.

11
votes

I have found that using header("Content-type: text/css", true); works for me. It prevents the server from outputing 2 HTTP headers for 'Content-Type'.

4
votes

Is there any output before the header is sent? BOM in the php file? A carriage return?

If you disabled error reporting, you may not see the error it should trigger.

Try adding ob_start() on top, it will resolve any issue related to headers already sent before any header() call.

If you have a BOM in your UTF8 file, you may want to remove it.

0
votes

I think the problem maybe due to mod_security which is serving a 401 error page (HTML) rather than the CSS. Try adding this to an .htaccess file in the web root of your website to see if this resolves the issue.

<IfModule mod_security.c>
    SecFilterEngine Off
    SecFilterScanPOST Off
</IfModule>
0
votes

The article Handle Images/CSS/JS as PHP without httpd.conf Using .htaccess helped me figure out the issue.

You basically do all the same stuff as everyone else mentioned (setting header in PHP, etc.), but also use .htaccess to set the AddHandler param.

<Files my_style.css>
    ForceType application/x-httpd-php
    AddHandler application/x-httpd-php .css
</Files>

This way you can name it with .css and still have PHP parse it.

0
votes

For Internet Explorer 9 serving HTTP 406 status code in the response header for a dynamically generated CSS file we:

  1. Removed the Apache mod_negiotiation module or added -Multiviews to the host configuration (or .htaccess).
  2. Activated Apache mod_rewrite
  3. Added a rewrite rule to the virtual host configuration or htaccess:

    <IfModule mod_rewrite.c
    
      RewriteEngine on
      RewriteBase /
    
      #serve CSS and JS from combine.php
      RewriteRule ^combine(.*) combine.php [NC,L]
    
    </IfModule>
    

Note: This solution is only good for servers/virtual-hosts not using Multiviews as removing mod_negotiation removes usage of this directive as well.

0
votes

Recently I had a problem like this for myself too. Nasty debugging is all I can tell about this. Not sure if this might help you people, but I hope it will. Cut to the chase.

Internet Explorer uses something called Mime-type sniffing, which simply reads 200 Bytes of THE FILE header.

I had a PHP script which had to return different video file (with data - the whole file) dependent on the parameter it had been supplied with.

My video request example: get-video.php?id=here_goes_the_id

$file = ''; // Get the video file path
if (is_file($file)) {
    header("Content-Type: video/mp4");
    header("Content-Length: " . filesize($file));
    readfile($file);
}
exit(); // This is the turnaround

You have to suspend your script immediately after it sends the file data. This prevents the IE Mime-type sniffing.

Hope it helps.