Force Download via Ajax and PHP

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 download

function 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



Leave a reply



Submit