In my html, I have
$('#vcc').click(function() { get_file() } );
function get_file()
{
$.ajax({ url: "test.php",context: document.body})
.done(function(text)
{
....
});
}
In test.php
I'm generating a pdf document.
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Content-Type: application/force-download");
header('Content-Disposition: attachment; filename=' . urlencode(basename("factures/facture_2015_03.pdf")));
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . strlen($response));
ob_clean();
flush();
echo $response;
If I call directly test.php, it's working, the file is downloaded.
Now I'd like to have it working with an ajax call. But I don't know what to put in the ...
I tried with a document.write
. The content of the pdf file is shown in my browser but not downloaded.
What can I do ?
EDIT:
Now my local.php
contains
<html>
<head>
<script type="text/javascript" src="js/jquery-2.1.3.min.js"></script>
<script type="text/javascript">
$( document ).ready(function() { document_ready(); } );
function document_ready()
{
$('#vcc').click(function() { get_ajax() } );
$.ajaxTransport("+binary", function(options, originalOptions, jqXHR)
{
// check for conditions and support for blob / arraybuffer response type
if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob)))))
{
return {
// create new XMLHttpRequest
send: function(_, callback){
// setup all variables
var xhr = new XMLHttpRequest(),
url = options.url,
type = options.type,
// blob or arraybuffer. Default is blob
dataType = options.responseType || "blob",
data = options.data || null;
xhr.addEventListener('load', function(){
var data = {};
data[options.dataType] = xhr.response;
// make callback and send data
callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
});
xhr.open(type, url, true);
xhr.responseType = dataType;
xhr.send(data);
},
abort: function(){
jqXHR.abort();
}
};
}
});
}
function get_ajax()
{
$.ajax({
url: "remote.php",
// data that you want send to PHP script
data: { fileId: "random", extraData: "some value" },
type: "GET", // or POST
dataType: "binary", // make our special transfer type
processData: false,
success: function(text)
{
var pdfContent = [text]; // change to Array
var fakeFile= new Blob(pdfContent, {type: 'application/pdf'});
SaveToDisk(fakeFile, "form1.pdf")
}
});
}
function SaveToDisk(blobURL, fileName) {
var reader = new FileReader();
reader.readAsDataURL(blobURL);
reader.onload = function (event) {
var save = document.createElement('a');
save.href = event.target.result;
save.target = '_blank';
save.download = fileName || 'unknown file';
var event = document.createEvent('Event');
event.initEvent('click', true, true);
save.dispatchEvent(event);
(window.URL || window.webkitURL).revokeObjectURL(save.href);
};
}
</script>
</head>
<body>
<div>
<input type="submit" id="vcc" value="Go"></input>
</div>
</body>
and remote.php
<?php
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . urlencode(basename("form1.pdf")));
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
$response = readfile("form1.pdf");
header('Content-Length:' . strlen($response));
ob_clean();
flush();
print $response;
?>
And the result
I'm not sure [my other solution with jQuery does not work in Firefox..]. Like many others said, you should not use AJAX/jQuery to make web browser download file.
Example:
page.htm with download link/button/anything:
<!doctype html>
<html>
<head>
<title>Download fake file from JS script example</title>
<meta charset="utf-8">
<script>
function downloadPdfExample()
{
// simple :)
window.location = "download_pdf.php";
}
</script>
</head>
<body>
Click on button below to start download:<br />
<button onclick="downloadPdfExample()">Start PDF download</button><br />
</body>
</html>
download_pdf.php file that will force browser to download file, not show in new card/current card:
<?php
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . urlencode(basename("form1.pdf")));
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
readfile("example.pdf");
flush();
I thought too much about JS code and forgot about PHP.
As you can see in example on PHP page ( http://php.net/manual/en/function.readfile.php#example-2524 ) readfile('filename'); does not return file content. It prints it on 'output'!
So.. this part of code:
$response = readfile("form1.pdf");
header('Content-Length:' . strlen($response));
Throws error! You cannot set response header AFTER you send file content (readfile send file content to browser, not put it variable $response!)
In $response is LENGTH of data sent to browser, so strlen($reponse) also does not work.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments