title: Chrome is misinterpreting a file attachment as a document
body: <p>I have a link that goes to a PHP script that generates a CSV file to be downloaded and   saved. I generate the Content-Disposition and Content-Type headers in the response. Every browser downloads the file fine <em>except</em> for Chrome (v19).</p>
  
  <p>The link is something like this:</p>
  
  <p><a href="http://hostname.com/controller/action/export">http://hostname.com/controller/action/export</a></p>
  
  <p>The headers returned from that request are:</p>
  
  <pre><code>Cache-control:no-cache, must-revalidate
  Connection:Keep-Alive
  Content-Disposition:attachment; filename=2012-03-14.csv
  Content-Encoding:gzip
  Content-Length:521
  Content-Type:application/vnd.ms-excel
  Date:Thu, 15 Mar 2012 05:17:55 GMT
  Expires:Mon, 26 Jul 1997 05:00:00 GMT
  Keep-Alive:timeout=5, max=92
  P3P:CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"
  Pragma:no-cache
  Server:Apache/2.2.11 (Win32) mod_ssl/2.2.11 OpenSSL/0.9.8i mod_autoindex_color PHP/5.2.9
  Vary:Accept-Encoding
  X-Powered-By:PHP/5.2.9
  </code></pre>
  
  <p>The Chrome developers tools shows that the network connection was <code>Canceled</code> and the console window shows the following error:</p>
  
  <pre><code>Resource interpreted as Document but transferred with MIME type application/vnd.ms-excel:
  </code></pre>
  
  <p>I have tried using different values for Content-Type, I have turned off the Cache-Control and Content-Type headers. I have tested using Javascript <code>location.href=</code>, an <code>&lt;a&gt;</code> tag, a <code>&lt;form action="POST"&gt;</code>, turned off Gzip compression, and various other methods to attempt to get Chrome to actually download the file.</p>
  
  <p>Every other browser downloads the file fine, so my question is: What is causing Chrome to interpret the request as a "Document" for display instead of an attachment?  Is there another header I'm missing or a header in the list that's confusing it?</p>
  
  <p><strong>EDIT:</strong> Here's the PHP code as requested, though it's a bit long:</p>
  
  <pre><code>function renderHeaders($filename = null) {
    header("Content-Type: application/vnd.ms-excel");
    header("Cache-Control: public, must-revalidate, max-age=0");
    if (is_string($filename)) {
      $this-&gt;setFilename($filename);
    }
    if ($this-&gt;filename === null) {
      $this-&gt;filename = 'Data.csv';
    }
    if ($this-&gt;filename) {
      header("Content-disposition: attachment; filename=".$this-&gt;filename);
    }
  }
  
  function render($outputHeaders = true, $to_encoding = null, $from_encoding = "auto") {
    if ($outputHeaders) {
      $this-&gt;renderHeaders();
    }
    if ($this-&gt;_tmpFile) {
      rewind($this-&gt;buffer);
      $output = '';
      while (!feof($this-&gt;buffer)) {
        $output .= fread($this-&gt;buffer, 8192);
      }
      fclose($this-&gt;buffer);
    } else {
      rewind($this-&gt;buffer);
      $output = stream_get_contents($this-&gt;buffer);
    }
    // get around excel bug (http://support.microsoft.com/kb/323626/)
    if (substr($output,0,2) == 'ID') {
      $pos = strpos($output, $this-&gt;delimiter);
      if ($pos === false) {
        $pos = strpos($output, "\n");
      }
      if ($pos !== false) {
        $output = $this-&gt;enclosure . substr($output, 0, $pos) . $this-&gt;enclosure . substr($output, $pos);
      }
    }
    if ($to_encoding) {
      $output = mb_convert_encoding($output, $to_encoding, $from_encoding);
    }
    $this-&gt;clear();
    return $this-&gt;output($output);
  }
  </code></pre>