Force Download via Ajax and PHP
You can't download files with ajax. So, if you have something that should happen on ajax, you should return url in response and apply it like document.location = "url"
to start download process.
One note here. As I remember, browser will block file download if it is initiated not by user click. So, this will work fine:
.click(function(){
document.location = "download url"
})
But if it is started not by user click, it will be blocked. So, code like this:.click(function(){
$.ajax({...,
success:function(download_url_from_server){
document.location = download_url_from_server;
}});
})
will be blocked by browser. So, if you want to pass some data with a post, you may submit a form into hidden iframe or to blank page using <form target="..."
: function checkToken(token){
var $form = $("#downloadForm");
if ($form.length == 0) {
$form = $("<form>").attr({ "target": "_blank", "id": "downloadForm", "method": "POST", "action": "script.php" }).hide();
$("body").append($form);
}
$form.find("input").remove();
var args = { a: "checkToken", b: token }
for (var field in args) {
$form.append($("<input>").attr({"value":args[field], "name":field}));
}
$form.submit();
}
And in script.php you need to execute code from download.php immediately, if token is Ok, or do a redirect to download script:header("Location: download.php?a=" . $filename)
Download file through an ajax call php
AJAX isn't for downloading files. Pop up a new window with the download link as its address, or do document.location = ...
.
download file using an ajax request
Update April 27, 2015
Up and coming to the HTML5 scene is the download attribute. It's supported in Firefox and Chrome, and soon to come to IE11. Depending on your needs, you could use it instead of an AJAX request (or using window.location
) so long as the file you want to download is on the same origin as your site.
You could always make the AJAX request/window.location
a fallback by using some JavaScript to test if download
is supported and if not, switching it to call window.location
.
Original answer
You can't have an AJAX request open the download prompt since you physically have to navigate to the file to prompt for download. Instead, you could use a success function to navigate to download.php. This will open the download prompt but won't change the current page.
$.ajax({
url: 'download.php',
type: 'POST',
success: function() {
window.location = 'download.php';
}
});
Even though this answers the question, it's better to just use window.location
and avoid the AJAX request entirely. Ajax File Download using Jquery, PHP
I think the problem is that you're trying to load a file result INTO #downloadmsg, which isn't going to work because .load() is only going to load results as HTML...NOT binary data or other encoding.
One approach that might work is creating a hidden iframe in HTML, like this:
<iframe id="secretIFrame" src="" style="display:none; visibility:hidden;"></iframe>
Then, set the attr of the iframe to your querystring:$("#secretIFrame").attr("src","myphpscript.php?option1=apple&option2=orange");
and then using PHP headers to force the download when the source is set (here's an example of an exporter header set from one of my scripts that uses an octet stream):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/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment;filename=data.xls ");
header("Content-Transfer-Encoding: binary ");
Hope this helps! Dowload file with ajax and php
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.
AJAX/PHP force file download display contents of zip file in the browser
Since you can't download files using AJAX
, The simplest solution is to return the file name to Javascript and use location.href and force file download.
<?php
$name = trim($_POST['searchItem']);
if (!file_exists("images/$name/$name.zip")) {
//creating a zip file
$zip = new ZipArchive();
$zip_file = "$name" . '.zip';
$zip->open("images/$name/" . $zip_file, ZipArchive::CREATE);
$files = scandir("images/$name/");
for ($i = 2; $i < count($files); $i++) {
$fi = $files[$i];
if (file_exists("images/$name/$fi")) {
$zip->addFile("images/$name/$fi", $fi);
}
}
$zip->close();
//force to download the zip
$file = "images/$name/$zip_file";
echo json_encode(['filename' => $file]); // return file name to Javascript
}
?>
Then in Javascript I use location.href
to force file downloadfunction search(item){
var search = new XMLHttpRequest();
search.open("POST","check.php");
search.onreadystatechange = function(){
if(search.readyState === 4 && search.status === 200){
var data = JSON.parse(search.responseText);
window.location.href = data.filename; // force file download
}
};
search.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
search.send("searchItem="+item);
}
Force download after ajax call
Putting elements in a form and submitting them just seems to hacky, and I don't feel comfortable using it.
When you are using these types of things I think you are risking a bit, the next versions of browsers may simply not support them.
Besides I am passing complicated arrays as options in my ajax call to the server, and it's not easy to convert them all into an html form, unless I serialize the arrays in a hidden element and unserialize it on the server side, but that's all too complex.
What I did instead was, when the ajax call is made, the server stores the output in a session, then it returns a unique key for that value, another page on the server will simply echo the output when that key is given to it as an input,
So user clicks on something, then an ajax call is made, then the server stores that in a session, then user clicks on a download link and then the server removes that session.
It may not be the most perfect solution specially since the user has to click twice, but it just seems more standard to me.
Downloading PDF file with JQuery AJAX and PHP
i don't think this approach to downloading a pdf will work. Javascript is sending the request, and php is sending the response. You want the response to go directly to the browser, not to javascript. You should change the download link to go directly to the download location. No ajax / javascript needed. Like this:
<a href="javascript:void(0)" onclick = "window.href='app/myPage/download?'+id">download</a>
Download a file by jQuery.Ajax
2019 modern browsers update
This is the approach I'd now recommend with a few caveats:
- A relatively modern browser is required
- If the file is expected to be very large you should likely do something similar to the original approach (iframe and cookie) because some of the below operations could likely consume system memory at least as large as the file being downloaded and/or other interesting CPU side effects.
fetch('https://jsonplaceholder.typicode.com/todos/1') .then(resp => resp.blob()) .then(blob => { const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.style.display = 'none'; a.href = url; // the filename you want a.download = 'todo-1.json'; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); alert('your file has downloaded!'); // or you know, something with better UX... }) .catch(() => alert('oh no!'));
Related Topics
Get Calling File Name from Include()
PHP - Swiftmailer Using Starttls and Self Signed Certificates
How to Get the Absolute Path to the Public_HTML Folder
How to Keep a PHP Session Active Even If the Browser Is Closed
Changes to Upload_Max_Filesize in Ubuntu PHP.Ini Will Not Take Effect
Save Accents in MySQL Database
Newline Not Working in PHP Mail
How to Extract Frames of an Animated Gif with PHP
MySQL Insert ....On Duplicate Update - Adds One to the Autoincrement
How to Insert JSON Array into MySQL Database
How to Remove Text Between Tags in PHP
How to Get Products from a Particular Category in Magento Ecommerce
Upload Progress Using Pure PHP/Ajax
Upgrading Laravel 5.5 to 5.6 Error
A Better Way to Replace Emoticons in PHP