I'm trying to make auto download file from URL with 301 Moved Permanently like this:
Download
But it does not auto download the image.
Instead it only displays the image on the new tab instead of providing the file as a download.
Please suggest any other way of doing this
Instead of using the download attribute in the tag, you might consider just changing the response headers instead.
In the response from the server, if you set the Content-Disposition header to attachment, like #BadPiggie said, then the image file will download instead of display.
If you choose to use this header like this, then the download attribute is not needed I believe.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
As you said in comment,
The endpoint just redirects (301) to a URL of image
(someurl.com/image.jpg)
The issue is in your endpoint myserverapi/download?fileId=123. Because the endpoint redirects you instead of serving the requested file. This means that the URL doesn't allow you to access the file for some reason.
Maybe, You are using a Temporary URL, So it's throwing 301 error after expiration. So there is nothing wrong with your HTML code!
So.. the problem is that the link opens in a new tab and that is NOT the desired behavior?
If that is the case change:
target="_blank"
for
target="_self"
Target blank forces the link to be opened in a new tab, check this: https://www.w3schools.com/tags/att_a_target.asp
u can use some server side script if you have the full path to the image, redirect to this page and download it from there
$filename = "https://developers.google.com/homepage-assets/images/chromeos-logo.png";
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename. '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
readfile($filename);
this will trigger downloading of the image not opening it
Assuming the question is dealing with a same-origin link, a possible cause for this behaviour is older Firefox versions which hadn't implemented propagating the filename across redirects — the feature seems to have been added somewhere between v78 and v91, which could very well have been after this question was asked.
In v91 this block is present in the HttpBaseChannel::SetupReplacementChannel function:
if (sameOriginWithOriginalUri) {
newChannel->SetContentDisposition(mContentDispositionHint);
if (mContentDispositionFilename) {
newChannel->SetContentDispositionFilename(*mContentDispositionFilename);
}
}
( at https://searchfox.org/mozilla-esr91/source/netwerk/protocol/http/HttpBaseChannel.cpp#4414 )
Note that mContentDispositionFilename is assigned with the download='...' attribute value at an earlier stage.
In v78 however this code is absent — see https://searchfox.org/mozilla-esr78/source/netwerk/protocol/http/HttpBaseChannel.cpp#4098
Related
I am trying to initiate the download of an mp4 file that is located at a url (I do not have access to the file itself). I do not want the video to play in the browser, and I do not want the user to have to leave the web page.
I have tried creating an <a> element and using the download attribute, but it has to be compatible with IE, which doesn't support the download attribute, so that is not viable.
I have tried window.open('https://example.com/file-name.mp4');, but some browsers will simply start playing the video in a new tab instead of downloading it.
I have also tried window.open('https://mywebsite.com/download.php?file-id'); where the download.php file checks to make sure the user is authorized to download the file, formats the url, sets Content-Type and Content-Disposition headers, and ends with readfile($file_url);. This works well except, on failure, the download.php page remains open. I would rather be able to display an error message on the original page than have to set up an error page for download.php.
I tried to use the above method with an AJAX call to avoid the redirect problem, but I cannot figure out how to take the response and start the download with it.
How can I initiate the download of the mp4 file without the chance of it playing in the browser or redirecting to another web page?
<?php
set_time_limit(0);
$file = 'file-name.mp4';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
if(!readfile($file)) {
echo "error occured!";
}
exit;
} else {
echo "Error file not found";
}
?>
I have <a> and inside its href attribute, I've got a Video URL from a 3rd-party api, when clicking on that <a> the browser opens a New Tab and Play the video instead of Downloading it!
PROBLEM: What I need to achieve is to download the video directly after clicking on that <a> instead of playing it in a New Tab and force the user to Right Click then choose Save Video As option to download it manually... Just click on Download and the browser starts to download that video!
NOTE: I am building a JavaScript App, so I need a solution in JavaScript not PHP, it has to be working on all browsers as well...
EDIT: I tried the download attribute and it doesn't work, because it's Same-Origin Only!
UPDATE: The only solution I found was a +7 years old, it manipulates with the .htaccess file, you can check it at this CSS Tricks Article, it has a common issue, I can't have 2 links: Watch Video and Download Video using this solution... Many developers mentioned this bug there, but no one fixed it yet!
Since the endpoint supports CORS, you can use my file download lib to save the content instead of showing it.
download("http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4");
Online Demo: http://pagedemos.com/v84rawmzntzt/output/
you need to set headers such as Content-Disposition from the server as follows
Content-Description: File Transfer
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="filename.jpg"
to allow previewing and download you might append these headers depending on query parameter for example if the url has ?download, append these headers to tell the browser to download the file instead of viewing it.
You can't change the header of the 3rd party server.
You don't want to implement a server that could proxying the request and update the header.
The only solution I can see is download and handling the content in browser js with request or axiosthen propose it to user (but you have to keep it in memory which might not fit for large video)
As it is a Video URL from a 3rd-party api, you can resolve the problem in two ways:
Contact the api-provider, ask them to add the header "Content-Type: application/octet-stream".
Proxy the 3rd-party api, and add the header "Content-Type: application/octet-stream" in the proxy.
Yes, the key is to set content-type header in http response.
My best guess would be redirecting user to a separate page to force browser download the file instead of viewing it (image, video, pdf)
PHP Example using readfile function create a download.php file
<?php
$file = 'monkey.gif';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>
Hope that helps.
Source
What I am doing is to using PHP to get an external file, and send it to client’s browser. But the following code doesn’t pop up the downloading prompt. Using Chrome's developer tool, I can see in Network -> Response that the data is correctly fetched. But nothing happens to the browser.
<?php
header("Content-Disposition: attachment;filename=Example.zip");
header('Content-Description: File Transfer');
header("Content-Type: application/force-download");
header('Content-Transfer-Encoding: binary');
header("Content-Length: 512");
header("HTTP/1.1 206 Partial Content");
$x=fopen("http://www.example.com/example.zip","r");
echo fread($x,512);
fclose($x);
exit;
?>
UPDATE: In fact, I have figured out where the problem was: I did not invoke the PHP using user's click, but javascript's XMLHttpRequest. When I directly visit my above PHP page, everything works perfectly. Sorry about that. But now the question would be: is it possible to trigger download prompt using javascript XMLHttpRequest?
UPDATE 2: So here is what I wish to accomplish: I have a page with a "download" button, clicking the button will trigger javascript XMLHttpRequest to invoke the PHP page (in this way, the browser address bar will remain the same, i.e. it will not visit the PHP page). I would like to use this background XMLHttpRequest to invoke the PHP page, which returns the content (with all legit headers, i.e. Content-Type, ...) that will invoke the download prompt for the user.
Don’t use this line:
header("Content-Type: application/force-download");
If you are forcing a zip file to download, use the actual MIME type for zip files:
header("Content-Type: application/zip");
How can I force the save file download dialog box when I click an <a> tag?. There is a PDF file available on a remote server and when a user clicks that link we want to download that PDF file to their local system.
Thanks
Normally when you link a file that file will always display inside of the browser because the browser loads it and automatically determines the content type based on the file extension. So when you click on a link like a jpg image pdf etc the browser knows it's an image/file and will display that file. You can of course always use the browser short cut menu and use the Save Target As option to save the file to disk.
If you want to do this automatically when a link is clicked from the server side, you have to send the file back yourself rather and add a couple of custom headers to the output. The way to do this is to use Response.TransmitFile() to explicitly send the file from your ASP.NET application and then add the Content Type and Content-Disposition headers.
So You neded to use headers liek below:
header('Content-Disposition: attachment; filename="filename.pdf"');
Here is an exapmle might help you :
http://www.west-wind.com/weblog/posts/2007/May/21/Downloading-a-File-with-a-Save-As-Dialog-in-ASPNET
change your header values..
Ex
header('Content-Disposition: attachment; filename="downloaded.pdf"')
path = "path/to/file.pdf";
$filename = "file.pdf";
header('Content-Transfer-Encoding: binary'); // For Gecko browsers mainly
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($path)) . ' GMT');
header('Accept-Ranges: bytes'); // For download resume
header('Content-Length: ' . filesize($path)); // File size
header('Content-Encoding: none');
header('Content-Type: application/pdf'); // Change this mime type if the file is not PDF
header('Content-Disposition: attachment; filename=' . $filename); // Make the browser display the Save As dialog
What he is looking for is not a open save dialogue while downloading something from the host.
He is looking to open a file from the client's file system. You must use the input type file, to do so. But you will not get much privileges to manipulate that using javascript.
And there is no way to prompt a window's save dialogue through standard html.
We need ActiveX or Flash to do it.
i want to create wallpapers page for my website. and i want people can download by clicking on download button directly rather than image view in browser and user right click on that and then save as image. is there any solution with java script?
You need to force the content type of the image being sent by the server. There isn't a way to do this client-side.
Content-Type: application/octet-stream
Content-Disposition: attachment;filename=myimage.png
You can force a download via a PHP (or other server-side language) script like this:
$file = $_GET['file'];
header('Content-Description: File Transfer');
header("Content-type: application/octet-stream");//notice this content-type, it will force a download since browsers think that's what they should do with .exe files
header("Content-disposition: attachment; filename= ".$file."");
readfile($file);
Then in your JavaScript code you can direct users to this script with the GET variable file being populated by the JavaScript.
$('a.download_link').on('click', function (event) {
event.preventDefault();//prevent the normal click action from occuring
window.location = '/path/to/server-side.php?file=' + encodeURIComponent(this.href);
});
This will add a click event handler to any links that have the .download_link class to direct the browser to the PHP script above to force a download.
Just use a hidden iframe that you set the source attribute on when you click the button.
HTML
<input class="download" href="http://site.com/imageHandler.ashx" value="Download"/>
Javascript
$("input.download").click(function() { $("iframeID").attr("src", $(this).attr("href")); });
You also need to set the content-type using the custom image handler (whichever server-side language you are using)