I have an unusual requirement. Essentially I need a way so that, when the user clicks on a link or button, they will receive a PDF. The tricky part here is that the server w
Tested to work in chrome:
function toBinaryString(data) {
var ret = [];
var len = data.length;
var byte;
for (var i = 0; i < len; i++) {
byte=( data.charCodeAt(i) & 0xFF )>>> 0;
ret.push( String.fromCharCode(byte) );
}
return ret.join('');
}
var xhr = new XMLHttpRequest;
xhr.open( "GET", "/test.pdf" ); //I had test.pdf this on my local server
xhr.addEventListener( "load", function(){
var data = toBinaryString(this.responseText);
data = "data:application/pdf;base64,"+btoa(data);
document.location = data;
}, false);
xhr.setRequestHeader("magic", "header" );
xhr.overrideMimeType( "application/octet-stream; charset=x-user-defined;" );
xhr.send(null);
You can change application/pdf to application/octet-stream to have download prompt. But it's pretty easy to download from the chrome's reader as well.
In firefox nothing happens I guess it's because I don't have a plugin to deal with application/pdf
installed. Changing to application/octet-stream will prompt a dl.
With IE I suppose you need some kind of VBScript/ActiveX hackery
If the file is huge, using data uri might crash the browser, in that case you can use BlobBuilder and Object URLs.
Instead of linking to the .PDF file, instead do something like
<a href="pdf_server.php?file=pdffilename">Download my eBook</a>
which outputs a custom header, opens the PDF (binary safe) and prints the data to the user's browser, then they can choose to save the PDF despite their browser settings. The pdf_server.php should look like this:
header("Content-Type: application/octet-stream");
$file = $_GET["file"] .".pdf";
header("Content-Disposition: attachment; filename=" . urlencode($file));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . filesize($file));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp))
{
echo fread($fp, 65536);
flush(); // this is essential for large downloads
}
fclose($fp);
EDIT: The only way to add headers to a request from inside a browser (client-side) is use the XmlHttpRequest setRequestHeader method.
xhr.setRequestHeader('custom-header', 'value');