I have a PHP script that downloads a PDF file from the server and prompts you to either open it, or save it. The script accepts a one time token, which is used in place of a file name, to hide the file name.
If you go to the actual php page, http://example.com/files/download/token the script works fine and it downloads the PDF.
I could just send people to that page with a standard link tag, but once the file downloads I need to update content on that page which is returned through that download script.
Is there any way to have ajax call open up a new window where the file will download and then return the data that I need to update the current page?
There is more to the download script, but the main piece is the actual downloading part:
header("Content-type: application/pdf");
$this->load->helper('file');
readfile("static/temp_statements/".$local_file_name);
unlink("static/temp_statements/".$local_file_name);
One trick that I have used in the past that might be useful to you is
Supply a query param in your ajax call to download the PDF. This will be a unique name.
The server process that streams the PDF for download sets a cookie with this unique name.
You poll in your page waiting for this cookie to appear.
When the cookie appears you can assume the file has downloaded, and you can do your contingent action.
And you do not need to open a window to make this happen. You could just append an invisible iframe like this:
$(some selector).append($("<iframe width='1' height='1' frameborder='0' src='" + url + "'></iframe>"));
In the interests of honesty and transparency, I originally found this idea from this SO answer and it worked for me: Detect when browser receives file download
Related
Using Codeigniter, I'm trying to do something basic.
The site has a form where users upload files for processing. After the files are processed, new files are created and saved in a zip file. Then I use $this->zip->download() to start the download.
But after that I can't do anything to refresh the upload form. And if I reload the view first, the download doesn't work.
All I want to do is upload the files, create the zip, download the zip and wind up with a clean upload form.
Any suggestions how to approach this?
I don't think you will be able to do it on the same page because of missmatched headers. You could try the following: when the zip is ready save it and name it some random/unique id/md5 anything and print the download link in the view with "click here to download your file" with target="_blank" param so it opens in a new tab. (usually browsers are smart enough that it will auto close it when you accept the file). And so you can reset the form in the view as well.
Another way could be with ajax and js i guess but that would be much longer to write.
Ps.: just dont forget to delete the files after x amount of time (if you dont need them)
I'm trying to create a 'download' page for my website. I'm using a url like this: http://example.com/download?file=21. The actual location of the file on the server is stored in a database along with the file ID. I would like the download page to display the name of the file that is being downloaded along with some other HTML. I'm having trouble figuring out how to both download a file and display output on the same PHP page.
All the advice I've seen for actually downloading a file with PHP requires changing the headers. Do I need to display the download page and then download the file with something like AJAX?
I would do it without ajax.
I would create a script to show the file with other html info http://example.com/file?id=21 and if the download param is set ( http://example.com/file?id=21&download=1 ) that script only prints the headers and sends the file.
Then, in http://example.com/file?id=21 I would create an empty iframe (in the code or dynamically with javascript) and then when a user wants to download the file you just have to set the url of that iframe to http://example.com/file?id=21&download=1 and the file will start to download. No need of ajax or reloading the website, only javascript to set the iframe url at the moment the user wants to download the file.
It's not the only way but I think it's a good one.
I want to allow a user to enter a date range and then be able to download an Excel file with data retrieved based on that date range.
Initially I had this working by submitting the form as a GET request for the same page. If the GET params are present the page will retrieve the data and output the needed headers and then the data. I would then exit; from the process to prevent the page from loading (since I had to send the headers with the Excel data).
This works. However I want to include a progress indicator that will go away once the data has been sent. However I cannot find a way to do this.
I can start such an indicator when the form submit button is pressed, but I cannot find a way to turn it off once the document had been output for download.
Ajax does not work in this sort of situation, btw.
Can anyone suggest how to do this? I've seen suggestion here on SO about loading the output into a hidden iframe but I do not understand how to do this myself.
Because I have no code on which I could base I will write you the theory mostly.
user requests to download a file
you load a page where inside you are creating the file, the process takes some time, during which you show the user a progress bar.
instead of throwing this file to the user with header function (which you cannot use as you already are printing on the screen) you save the file into a temp directory. preferably call it with a random name, or a timestamp.
by the end of file creation print on the screen a JavaScript command like this:
<script language=”JavaScript”>
self.location=”download.php?file=whatever_you_called_it.xls”;
</script>
set the header for the Excel download with something like this:
header('Content-disposition: attachment; filename=your_excel_file.xls');
header('Content-type: application/xls');
readfile('tmp_dir/whatever_you_called_it.xls');
unlink ('tmp_dir/whatever_you_called_it.xls');
its always good to clean the things after yourself. be aware that it is possible that something does not get deleted. So preferably you would have a garbage collector anyways. And keep files out of public directories
Obviously, if the data is not sensitive, then you can simply set javascript directly to the file and the browser will download it directly. But then you would need some kind of garbage collector to clean all these files that are created... it would be messy...
Actually I have some download link on my website something like "http://www.example.com/somesong.mp3". Now when user click on this link they get somesong.mp3 but I want to change it before they download. I found many scripts that made it possible but didn't get exact right script. Because I want that when the user clicks on download link the file downloading should be started just after the click with the new file name as I want to use.
But in all the scripts which I downloaded, first the php processing starts for a few minute (I think it depends on the file size) and then rename it. Is there a way to direct force the file in header with new file name.
Thanks.
try this
header("Content-Disposition: attachment; filename=whatever you want");
In a project I'm working on, the client has required that every time a user clicks on a link to download (they will be downloading a video or mp3), there should be a log kept of who has downloaded what and when.
I have a table in my database set up to record the User ID, the File ID, and the date when it was downloaded. However, I don't know how to do this, as the link is basically an tag (obviously).
What is the best way to achieve this?
Probably the simplest solution would be to write simple onclick ajax event.
If you want noscript solution you'll have to create some download wrapper, that'd serve you proper file. Just create special route and controller (eg. /downloads/filename), increment download meter for this one and return asset instead of html response. Don't forget to set proper Content-Type header tho.
There's also IgorwFileServeBundle that could help you loads.
Instead of linking to the MP3 file, you'll have to funnel the download through a PHP script that writes to the database and then sends the MP3 data with with the right headers. For maximum performance use the "X-Sendfile" header instead of the PHP readfile function.
Alternatively you could set up a cron job for a Symfony console command line tool that parses the Apache access log and writes to the DB whenever it encounters an MP3 file.