• Sign in to Neowin Faster!

    Create an account on Neowin to contribute and support the site.

  • 0
Sign in to follow this  

Using header() to force download not working in Chrome or Firefox

Question

game_over    802

I have created an mp3 downloader script which forces downloads of MP3s that are located outside of the web root. I've received a few support requests saying it's not working.. I originally only tested it in Safari and it worked fine, so I tested it in Chrome and Firefox and can confirm it returns a 404 error in both of those browsers.

In Chrome console it shows: net::ERR_INVALID_RESPONSE

download.php:

header("Content-Description: File Transfer");
header("Content-Type: {$mime}");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download"); 
header("Content-Type: application/download");
header("Content-Disposition: attachment; filename={$filename}");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($file));
while(ob_get_level()) ob_end_clean();
flush();
readfile($file);
exit;

 

I have checked all paths and variables.. everything is set, exists and readable.

If i remove application/force-download and application-download it loads the in browser mp3 player but returns a 404... so it looks like it can't find the file outside of web root - does Chrome/Firefox not allow that?

It is definitely working in Safari

Any ideas?

Share this post


Link to post
Share on other sites

4 answers to this question

Recommended Posts

  • 0
pqt    275

Check your Inspect Element tool on Chrome and see if it's blocking it client sided, I ran into issues with loading javascript files / modifying css through an iframe for security reasons. If you're on a windows device using safari, you're using a very outdated version (merely an assumption you're on windows) which may not have included a patch for cross-site anything.

I know that you get into a really grey area when you start using cross-site downloads without the appropriate allow-content headers on the receiving and requesting servers.

Share this post


Link to post
Share on other sites
  • 0
The_Decryptor    1,105

A few of these headers are meaningless outside of email (Content-Description and Content-Transfer-Encoding), and overwriting the content-type multiple times won't help much either (You ideally want to either use the original mime-type, or application/octet-stream. I have no idea what uses "download" or "force-download").

It returning a 404 is the more likely problem, PHP is actually using the $filename and $mime in the headers right? (Been ages since I've used PHP) It's also odd that you're just downing normal string concatenation for the filesize, but not for other headers.

Share this post


Link to post
Share on other sites
  • 0
game_over    802

A few of these headers are meaningless outside of email (Content-Description and Content-Transfer-Encoding), and overwriting the content-type multiple times won't help much either (You ideally want to either use the original mime-type, or application/octet-stream. I have no idea what uses "download" or "force-download").

It returning a 404 is the more likely problem, PHP is actually using the $filename and $mime in the headers right? (Been ages since I've used PHP) It's also odd that you're just downing normal string concatenation for the filesize, but not for other headers.

Thanks for your input, i removed the 'meaningless' headers and it still works in Safari so i'll leave those out. It didn't fix the chrome issue though.

Share this post


Link to post
Share on other sites
  • 0
DeathLace    11

This has always worked for me:

  • $file = "filename.ext";
  •  
  • // Quick check to verify that the file exists
  • if( !file_exists($file) ) die("File not found");
  •  
  • // Force the download
  • header("Content-Disposition: attachment; filename="" . basename($file) . """);
  • header("Content-Length: " . filesize($file));
  • header("Content-Type: application/octet-stream;");
  • readfile($file);

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.