is there a way to prevent a browser from opening an mp3 in a new browser window?
i have a normal link to mp3 file like
some.mp3
and of course you can download it with right click -> save as. but some users don't know that. so if they click on a link, a new window opens where they can listen to that mp3.
issue is, i want the users to download the files once instead of listen to them thousand times over my server ;)
Through html only you cannot force the link to open a file save dialog.
Instead you can achieve that through PHP and with some custom headers as seen here
A simple download.php file could look like:
<?php
$file = $_GET['file'];
$dir = "path/to/files/";
if(!file)
{
die('file not found');
}
else
{
$local_file = $dir . $file['filename'];
$file = fopen($local_file, "r");
header("Cache-Control: public");
header('Content-Type: application/octet-stream');
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$file");
header("Content-Transfer-Encoding: binary");
// set download rate
$download_rate = 100.0;
// fetch the file
fread($file, round($download_rate * 1024));
// close the file stream
fclose($file);
}
?>
Where you can specify the directory where all your files as saved, as well as a download rate if needed to limit the speed at which the file can be downloaded.
Update
Forgot to mention that you will then change your links to:
some.mp3
where test.mp3 will be changed to your particular download
quick and dirty: maybe you .zip it...than the browser automatically downloads the file
thanks for your script. it didn t worked out for me, because the $local_file variable wasn't build right.. don t ask, not really a php pro. still your post put me in the right direction. here s my solution
<?php
$downloadfile = "directory/".$_GET['file'];
$filename = $_GET['file'];
$filesize = filesize($downloadfile);
header("Content-Type: audio/mpeg3");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Length: $filesize");
readfile($downloadfile);
exit;
?>
oh, and for other php-dummies: NO WHITESPACE AT THE BEGINNING OF THE SCRIPT!!!
Related
I have headers which force a file download, rather than viewing it in the browser but I need to give that option. I've looked at several posts on Stack Overflow which answer this question (eg How to force files to open in browser instead of download (pdf)?) but I am still not getting the desired result, so I wanted to check if I'm missing something.
Here are my headers to force a download
$file = 'file.pdf';
$filePath = 'path/to/file.pdf';
header("Cache-Control: public");
header("Content-Length: 20000");
header("Content-Description: File Transfer");
header("Content-Type:file");
header('Content-Disposition: attachment; filename="$file"');
header("Content-Transfer-Encoding: binary");
readfile($filePath);
And here are the header to try and display the file in the browser
header("Cache-Control: public");
header("Content-Length: 20000");
header("Content-Description: File Transfer");
header("Content-Type:file");
header('Content-Disposition:inline; filename="$file"');
header("Content-Transfer-Encoding: binary");
readfile($filePath);
So the only change is the content-disposition header.
However, I am still just being shown the markup in the browser (see image).
Any ideas?
Many thanks
You are still using inline for content-disposition when you want to instruct browser to perform a download. Try use attachment instead.
more detais: Content-Disposition
I am offering a pdf document in the form of a download from my website via a landing page.
I want to hide the URL/link that displays in the address bar and when i hover over the download button on the web page so that the link cant be shared.
What is the best way to do this? Please explain carefully.
Thanks
Ok, you cannot do that with plain HTML. You can use all kind of tricks but they can be a problem to the user experience, you are to use a server side language.
What you can do is create a php page, name it the way you want (let's say download.php), and link to that one. The page should be something like this:
// Path to the file
$path = '/home/folder/yourfile.pdf';
// This is based on file type of $path, but not always needed
$mm_type = "application/octet-stream";
//Set headers
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($path)) );
header('Content-Disposition: attachment; filename="'.basename($path).'"');
header("Content-Transfer-Encoding: binary\n");
// Outputs the content of the file
readfile($path);
exit();
This way you just link to your download.php page and it downloads/opens the PDF, like so:
Download
Edited based on BenjaminC suggestions
The other chance you have is to connect this to a database. The database has a table named downloads_table and inside you have 2 fields:
secret: char(32)
downloaded: int(1) dafault 0
Then you create an md5 string
$secret = md5(rand(1000, 9999999));
Place it inside the secret field, create the link:
Download
The user receives/sees a link, when pressed you are to edit the first line of the above code to check in the db if downloaded field = to 0 than procede to download, otherwise the person sees an error page.
This is so that it can be downloaded only once.
(Edit)
If in the future, this gets useful for anyone, the functionality can be seen in this fiddle: https://jsfiddle.net/aznjr87g/
It downloads 2.1.3 jquery.min.js from google.
(Edit end)
This can be achieved using Html5 's Download attribute.
Download PDF
If you hover your mouse over that, it simply shows yoursite.com/#
Place this somewhere in the body of the webpage:
And place this somewhere in the webpage:
<script>
function download() {
document.getElementById("download").src = "/path/to/download";
}
<script>
Then, on the element of the button (In the example of a div) do this in the tag:
<div onclick="download()"> </div>
However if it's a link you will want to do:
An element needs a href to work properly.
In my website I stream users mp4 content. I also allow users to download.
However in Chrome it seems to automatically play the file in an internal player instead of downloading the file.
How do I force the browser to download the file instead.
Regards and thanks
Craig
You have to use the HTTP header "Content-Disposition" and 'Content-Type: application/force-download' which will force browser to download the content instead of displaying it there.
Depending upon the server side language you are having the implementation differs. In case of
PHP:
header('Content-Disposition: attachment; filename="'.$nameOfFile.'"');
will do the job for you.
Ofcourse to simplify and generalize this for all your files, you may need to write a method which will route a link to downloadable content.
The link you can show in the html will be like:
Click here to Download Hello.mp4
And in the server side, you need a script which is being called on /downloadFile (depending on your routing), get the file by id and send it to user as an attachment.
<?php
$fileId = $_POST['id'];
// so for url http://yoursite.com/downloadFile?id=1234 will download file
// /pathToVideoFolder/1234.mp4
$filePath = "/pathToVideoFolder/".$fileId."mp4";
$fileName = $fileId."mp4"; //or a name from database like getFilenameForID($id)
//Assume that $filename and $filePath are correclty set.
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Content-Type: application/force-download');
readfile($filePath);
Here 'Content-Type: application/force-download' will force the browser to show the download option no matter what's the default setting is for a mime-type.
No matter what your server side technology is, the headers to look out for are:
'Content-Description: File Transfer'
'Content-Type: application/force-download'
'Content-Disposition: attachment; filename="myfile.mp4"
Sounds like you are using a direct href to the mp4. If you are using any server side languages (i.e.asp.net, php, etc) language on your website you can force a download. In asp or .net you can use HttpHandlers with "content-disposition","attachment; filename=fname.ext"
or return File() ActionResult in MVC. Let me know if you can use any server side code and I can provide some code.
Alternatively you can try the html5 download attribute: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a?redirectlocale=en-US&redirectslug=HTML%2FElement%2Fa#attr-download
i.e. <a href="http://www.w3schools.com/images/myw3schoolsimage.jpg" download="downloadfilename">
Or, try javascript/jQuery. Here is a plugin: http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/
Setting the Content-Disposition header should fix it.
Content-Disposition: attachment; filename=whatever.mp4;
Either in the server settings or in the preprocessing of the page.
if you want a cross browser solution
you need a server-side code to download the file
example:
I am working on jsp technology, if you can use jsp in your website you can try the following code in the file download.jsp:
<%# page import="java.io.*, java.lang.*, java.util.*" %>
<%
String filename=request.getParameter("filename");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment;filename="+filename);
%>
<%
/*
File file = new File(filepath+filename );*/
String path = getServletContext().getRealPath("/mp4/"+filename);
File file = new File(path);
FileInputStream fileIn = new FileInputStream(file);
ServletOutputStream out1 = response.getOutputStream();
byte[] outputByte = new byte[4096];
//copy binary contect to output stream
while(fileIn.read(outputByte, 0, 4096) != -1)
{
out1.write(outputByte, 0, 4096);
}
fileIn.close();
out1.flush();
out1.close();
%>
you can put the code above in a file: download.jsp
then in your page links you will use it like:
song1
with my best wishes to you
You can get it done in a couple of ways. I'm not sure you use IIS or apache and which server side language you are using, but the techniques are similar for all.
You can add the MIME type application/octect-stream to the extension .mp4 in your IIS or apache, sothat all files with extension .mp4 will be shown with a download prompt. This is the most easy and sure fire way of showing the "download" prompt.
Plz see the example below.
http://www.codingstaff.com/learning-center/other/how-to-add-mime-types-to-your-server
In the above example, instead of setting video/mp4 fpr .mp4 extensions, change it to application/octect-stream
Also, the same can be done via server side code as well, (PHP code). The code will be similar with ASP.NET also,please google for "force file download"
$file_url = 'http://www.myremoteserver.com/file.mp4';
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file_url) . "\"");
readfile($file_url);
Why not simply use download attribute? Today is the simplest way.
<a href="/images/myw3schoolsimage.jpg" download>
See more here.
I'm trying to show my PDF files in my webpages but block the direct access to the files.
I'm trying to do this by using a .htaccess file like this:
order deny,allow
deny from all
allow from {MY_IP}
Where MY_IP is my server IP address (ex. 11.22.333.444), but when I do this my server can't access the files anymore. I'm showing the PDF's with this code:
<object data="downloads/PDF/doc.pdf" type="application/pdf" width="100%" height="100%">
<p>It appears you don't have a PDF plugin for this browser.
You can <a href="doc.pdf">click here to
download the PDF file.</a></p>
</object>
The webpage just stays blank (it can't load it).
Is there anything I'm missing with .htaccess?
Thanks for helping in advance!
Marc
You can check the referring website to see if it's your own with .htaccess
RewriteEngine On
RewriteCond %{HTTP_HOST}##%{HTTP_REFERER} !^([^#]*)##http?://\1/.*
RewriteRule .*\.pdf [NC,F]
That will fail with a forbidden directive (403 error). NC is case insensitivity. The server would need to be configured to show something in the event of a 403 error.
In PHP
Additionally you can check this sort of thing with a dynamic page that allows the download. Here's an example of how to do this with PHP:
<a href='/download.php?f=myfile&fd=mypath'>Download my PDF</a>
We're taking the .pdf off of the name in the link for security reasons. You could do something like base64_encode the name, but this won't stop a knowledgeable attacker from trying to exploit your system. The f variable is the filename (pre-period) and the 'fd' would be the folder (or path).
Example dirs could include pdfs or resources/pdf.
It can't start or end with a /. We're not allowing periods in paths or filenames so someone can't do something like pdf/../../...
Code for download.php
<?php
if((preg_match('!^[A-Za-z0-9_-]+$!',$_GET['f']))&&(preg_match('!^[^/][/A-Za-z0-9_-]+[^/]$!',$_GET['fd']))){
//we're hard-coding the line so someone can't spoof something like .htaccess
$tempPath = $_GET['fd'];
$tempFilename = $_SERVER['DOCUMENT_ROOT'].'/'.$tempPath.'/'.$_GET['f'].'.pdf';
//Make sure it's a real file
if(is_file($tempFilename)){
$referrer = $_SERVER['HTTP_REFERER'];
$serverName = $_SERVER['SERVER_NAME'];
//check the referrer
if(strpos($referrer, $serverName)){
$new_filename = $_GET['f'].'.pdf';
// We'll be outputting a PDF
header('Content-type: application/pdf');
// It will be called downloaded.pdf
$hString = 'Content-Disposition: attachment; filename="'.$new_filename.'"';
header($hString);
// The PDF source is in original.pdf
readfile($tempFilename);
} else {
//offsite link
header('Location: /download_policy.php');
exit();
}
} else {
//maybe an old file? Give them the homepage
header('Location: /');
exit();
}
} else {
//hacking attempt
header('Location: /');
exit();
}
?>
I use this code below to hide stream url of songs for my wordpress site … this mean instead of: example.com/audio.mp3 url is example.com/streem.php?id=53502
I have tested it with default HTML 5 player and it works on chrome and IE, but this is not working with this player: http://goo.gl/HziDr
Can anybody tell me is my code ok?
Code of streem.php is:
<?php
require('./wp-config.php');
$wp->init();
$wp->parse_request();
$wp->query_posts();
$wp->register_globals();
$attachmentID = $_GET['id'];
$attachment = get_attached_file( $attachmentID , false );
header("Content-Transfer-Encoding: binary");
header('Content-Length: '. (string)filesize($attachment)); // provide file size
header('Content-type: audio/mpeg');
header('Cache-Control: no-cache');
readfile($attachment);
exit;
?>
I don't know that player, but it's possible that it isn't content-type aware and requires a file extension to work. You could append
'&fmt=.mp3'
to your URL and see if that helps. Your PHP script should ignore that query parameter but hopefully the player will see the .mp3 extension and then work.