I want my mobile webapp be able to download files. My Android device unfortunately tells me it does not support file download via jquery plugin jquery.fileDownload.js...
So I just send a jsonP (cross domain, because my app runs on another server) request.
My php script looks
ob_clean();
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="file.JPG"');
readfile('/var/.../file.JPG');
die();
In my android chrome browser nothing happens after I send the jsonp request.
What I am doing wrong? Isnt it possible to download files via jsonp? Same code tested
on my desktop browser works perfectly.
Thanks in advance.
JSONP requires you to send back actual executable javascript code. You're just dumping out some essentially random bytes, which your browser will try to execute, and fail miserably.
You need to do some reading first: http://en.wikipedia.org/wiki/JSONP
You'd need to respond with a proper JSONP callback, and include your file data as a parameter, e.g.
header('Content-Type: text/javascript');
echo "jsonCallback(", json_encode(file_get_contents('your file here')); , ");"
Related
I'm using Retrofit 2.0.0-beta2 and I need to download some files from my PHP server. My first approach which worked was to directly use the GET method from its relative server path and I was getting the correct bytes.
Now I've tried something more secure that delivers the file to me based on some checks. It automatically fetches the file path from the DB and checks if the user session is correct. This works in browser tests, both Chrome PC and Chrome from Android correctly download some photos.
I'm serving the file using the X-Sendfile header like so:
header("X-Sendfile: $file_name");
header("Content-type: image/jpeg");
header('Content-Disposition: attachment; filename="' . basename($file_name) . '"');
The Android-side call looks like this:
#Streaming
#GET("/card/download")
Call<ResponseBody> getCard(#Query("filename") String filename);
All I'm getting when opening the files is the echoed text response from server. Is there any way I can receive the "correct" files?
Apparently there was some sort of problem installing the mod.
I also updated OkHttp to version 2.7.0
I am using the following code which I referred from the php.net example:
<?php
// open the file in a binary mode
$name = './db.sqlite';
$fp = fopen($name, 'rb');
// send the right headers
header("Content-Type: application/force-download");
header("Content-Length: " . filesize($name));
// dump the database and stop the script
fpassthru($fp);
exit;
?>
When I try to run this PHP script from the URL of my browser, I get the warning:
Cannot modify header information - headers already sent by
My requirement is to basically set up a PHP script which I can use to download the .sqlite file in my iOS app. But I think first it must work directly through the URL. I am new to PHP so please guide me.
I also tried to find out why am I getting this warning in the following link:
http://www.tech-recipes.com/rx/1489/solve-php-e
But it didn't solve my problem.
Question 2.) I have planned to use NSURLSession to get the file in my iOS app's sandbox, once the PHP script is up and working. Is this the correct way?
I could not get my PHP working correctly so I found a workaround.
I used NSURLRequest to point directly to the sqlite file residing on the server and then used NSData to store the contents of it. I then stored the file in the sandbox of my app(simulator) and I am able to query the database.
Important lesson that I learnt: "SQLite database files are not human-readable"
I did an xml file and force download it by these headers:
header('Content-disposition: attachment; filename="export.xml"');
header('Content-type: application/xml; charset=utf8');
readfile('export.xml');
But before the download I see a dialog that this file can be harmful for my computer? How to get rid of this dialog? Maybe my headers is wrong?
upd Well, can do nothing, I did a test on my test-hosting, u can check it here: site with generation link, and an xml file as is: export.xml
Try changing application/xml to text/xml. Probably your browser thinks that application means executable.
Try this :
<?php
header('Content-disposition: attachment; filename="export.xml"');
header('Content-type: "text/xml"; charset="utf8"');
readfile('export.xml');
?>
Note: This does not solve your issue, however it did solve an issue I had on my computer giving that notice (windows, chrome, apache webserver, PHP 5.4.10). I leave it here for future visitors.
Some browsers do not only look for the headers but also for the "filename" in the URL.
For example if you download a PHP file that contains XML, the browser might identify it as a dangerous file (because it can be executed on your system or is not within some whitelist or what not):
http://example.com/xml-download.php
A simple solution is to make this file not end with .php any longer, for example by adding a ?:
http://example.com/xml-download.php?
And continue with that to even signal the filename that way:
http://example.com/xml-download.php?export.xml
(the last one is not necessary but can be useful especially with some older browsers)
My test server is apache 2 to work php coding. i want to create a mp3 server.
Everything is working fine, however today i tried to build an admin page by taking the mp3 info, change it, delete etc. There is a play button in page for selected mp3, when clicked to play button, file loading with header option and playing,
Sample code is here:
session control &
$filename = '/home/bla..bla/mp3/'. $_GET['v'] . '.mp3';
if(file_exists($filename)) {
header('Content-Type: audio/mpeg');
header('Content-length: '.filesize($filename));
header('X-Pad: avoid browser bug');
header('Cache-Control: no-cache');
readfile($filename);
}else{
exit();
}
Everything looks fine, but when i click to another button (e.g. search again mp3 with ajax code or take value with javascript in same page) nothing is happening.
Page is waiting to load mp3 file. looks like blocking request. when mp3 loading %60 or %70, query is coming.
if i can't find a solution,i will be killer :)
ps: my system build on apache2, PHP5 , MySQL, using audio tag in admin page but same problem with jplayer.
Most likely you're running into session locking. When requesting a page in which you session_start(), the session file is opened and locked to prevent problems with concurrent access. The file stays locked until the current script is finished. While the file is locked, other processes can't access it and will wait until it becomes unlocked.
Before you do any long-running tasks like streaming an MP3 file, unlock the session with session_write_close.
Even better, let the web server handle the mundane task of streaming a file, don't keep a PHP process busy with it. Try mod_xsendfile.
I am currently developing an application in PHP in which my server (a dedicated server) must to download a file, and the user should download the file in same time.
Here is an example :
Server start to download a file at a time A.
User wants to download this file at the time A + 3 seconds (for example)
I already solved the problem :"If the user downloads the file faster than the server..". But I didn't know how to make a php script in which the user is gonna to download the full file (it means that the size must be the full size of the file, not the size it's currently downloaded at the time A+3seconds). I already make that :
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$data['name'].'";');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.$data['size']);
readfile($remoteFile);
But it doesn't work, the user is gonna download just the size it is currently on the server (which corrupt the file) and not the full file...
If you have any solution, thank you.
You could probably pipe the file manually, by opening the connection and reading until you're past all headers. Then once you've figured out the Content-Length, send that to the user and just echo all remaining data you get (do use flush() and avoid output buffers).
Pseudocode(-ish):
open the file
# grab headers
while you didn't get all HTTP headers:
read more
look for the Content-Length header
send the Content-Length header
# grab the file
while the rest of the request isn't done
read more
send it to the user
flush the buffers
done
Expanding on #Tom answer, you can use cURL to greatly simplify the algorithm by using the CURLOPT_HEADERFUNCTION and CURLOPT_READFUNCTION callbacks - see curl_setopt().
Don't send the content-length header. It's not required assuming you're using http 1.1(your webserver almost certainly does). Drawback is their browser cant show download time/size remaining.