Prompting user to save file using a 'Save-as' dialog? - javascript

I currently have this code:
function download(filename, text) {
var pom = document.createElement('a');
pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
pom.setAttribute('download', filename);
pom.click();
}
download('test.html', string);
The string contains a lot of html code that gets written in an .html file.
The above code is working perfectly:
On a button click, the browser (chrome) automatically downloads an html file with the string content written in it.
Now, what I want to do is, instead of chrome downloading the file automatically, it should open a "save-as" dialog box and ask the user the location and name of the file, and then download it to that location.
A quick simple reply would be really appreciated.

My browser was set to automatically download all files in default location which is why not only this file but all other files from my browser were downloaded directly without the save prompt dialogue. Changing the settings in browser to 'always ask the download location' worked.

The only way to do this is to set the header of the file on the server, like so:
<FilesMatch "\.(?i:pdf)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
The download attribute does not allow you to change the filename or filetype any more as it is an obvious security risk.
What you are trying to do it replicate the right-click - save-as dialogue but I'm afraid that is not possible at this time.

Related

How can I add a mechanism on a web page to download an html file to their mobile device? (The link opens page rather than downloading the html file)

I have an html file that I would like to make available for offline use. This can be achieved easily by simply right clicking on the link on a desktop browser, then choosing "save as".
However, on a mobile device, I have tried using the download attribute on the anchor tag like so:
<a href="index.html" download>Download the page here.</a>
This seems to just take me to the page instead of downloading it.
My main goal is just to allow the user to download an html file to their mobile device.
There really isn't a right-click on mobile and holding down on the link shows a menu, but download isn't among them. The mobile browser itself may have a mechanism for saving a page once opened, but this would be sort of hard to walk the user through, and of course I'll have no idea what the mobile browser the user is using.
A special note here, the webpage I am trying to download does not have assets like images or style script files that need loaded in, all the assets are self-contained in the html file itself.
I actually came up with a solution to the problem, so I'll share it here, but I'm finding it hard to believe that there is not an easier way to do this.
My solution was essentially this, make an asynchronous request for the html file and read its text as a string. Then use that string to make a text blob and download it. Furthermore, to make sure the asset could be obtained from a local machine I served the data with a php file containing a header to ignore the cross origin restriction. (I didn't use fetch because I wanted to use settimeout).
To request an index.html file from the location https://www.mypage.com/:
Here is the downloader.php file located in the base directory:
header('Access-Control-Allow-Origin: *');
?>
<?php include_once 'index.html';?>
The html file the user clicks:
<!DOCTYPE html>
<html>
<body>
<button onclick="downloadPageAsText('https://www.mypage.com/downloader.php', 'index', '.html');">Download</button>
</body>
</html>
The functions to allow downloading:
function downloadPageAsText(url, basename, suffix){
let xhttp = new XMLHttpRequest();
xhttp.timeout = 1000;
xhttp.ontimeout = function(e) {
alert("Request timed out. Try again later");
};
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
saveStringToTextFile(xhttp.responseText, basename, suffix);
}
};
xhttp.open("GET", url, true);
xhttp.send();
}
function saveStringToTextFile(str1, basename = "myfile", fileType = ".txt") {
let filename = basename + fileType;
let blobVersionOfText = new Blob([str1], {
type: "text/plain"
});
let urlToBlob = window.URL.createObjectURL(blobVersionOfText);
let downloadLink = document.createElement("a");
downloadLink.style.display = "none";
downloadLink.download = filename;
downloadLink.href = urlToBlob;
document.body.appendChild(downloadLink);
downloadLink.click();
downloadLink.parentElement.removeChild(downloadLink);
}
Is there an easier way to allow the user to download an html file to their mobile device?
After help in the comments I found that adding the Content-Disposition header in the PHP file prompts the mobile browsers to use their download mechanisms.
It looks like there are 2 relatively simple ways to cause the html file to download.
You can use the anchor tag's download attribute which is supposed to prompt the browser to download the file instead of displaying it. Here is an example of its use:
Click to download
However, this only works for same-origin URLs, so although it may fit your use-case but not mine as I need the file to download from cross-origin URLS.
A second simpler way of making the html file download rather than display (using PHP), is to use the Content-Dispostion header which tells the users browser it should be downloading the file.
Here is an example of a PHP file called download.php, which will cause desiredpage.html to download with a suggested name of suggestname.html, using just an anchor tag from the client side.
<?php
$contents=file_get_contents("desiredpage.html");
$filename="suggestedname.html";
header('Access-Control-Allow-Origin: *');
header("Content-disposition:attachment;filename=".$filename);
echo $contents;
?>
And here is the anchor tag on the client-side:
Click here to download
Reference:
Download Link not working in html
With useful comments from:
Anirban and Christopher.

Javascript Check whatever link is download link or webpage link

It there anyway to check link whatever is a download link like http://ipv4.download.thinkbroadband.com/5MB.zip
or normal web like open https://www.google.com
Currently I am using Electron and want to check if link is download link it will download and not open new browser but if not it will open in browser window
Make an HTTP request and check the Content-Type and (if it is there) Content-Disposition headers.
If Content-Disposition says it is an attachment, then it is a download. If it says it is inline, then it is intended to be displayed in the browser window.
If Content-Disposition isn't specified, then you'll need to make the decision based on the MIME type. e.g. text/html should probably be shown in the browser window.
May be check the end of the link... if it ends with .zip .jpg .pdf .... it is a file.
Or .html ... it is a page.

Change file name when using window.location to download

I'm using window.location to download my image. It isn't in HTML because I generate the image on the server and then send it back down so it looks like :
window.location = data.url;
I've seen a few other questions but they suggest the download attr which I don't have because there's no HTML.
Is there a way I can change the file name?
Front-end solution
The only thing you can do on the front-end side is to change your code to HTML <a> element with download attribute:
Download
When user clicks this link, the browser forces download and saves the file with given filename. You can read more about it in this post. It's quite a new feature so check the browser support.
Back-end solution
If you can modify the server-side code then you should use content-disposition header as defined in RFC 2183.
content-disposition: attachment; filename=very_important_report.pdf
I've been wondering about it as well and saw this post but I was also using vuejs for the project and want the export to be continues even when switching from one page to another so I tried something and it did work here is another solution:
var link = document.createElement('a');
link.setAttribute('href', '<yourlink_or_data>');
link.setAttribute('download', 'filename.ext');
link.click();
You can't change the filename on the client side. You would have to do that on the server.
You could set the content-disposition header (on the server side) like this:
Content-Disposition: attachment; filename="yourname.gif"

Linking to a download in HTML

I have to create a online time-table for the school. The part what is troubling me at the moment is not to be able to download a file by clicking on the filename.
I try to download a file by clicking on a button or a link with html/php maybe javascript but for javascript I should somehow combine php and javascript because javascript has no readfile-function.
Some of my attempts:
Download
This just shows the content of the file in the web browser but I am not able to download it. The content of my testmove.txt is testmove123, so I just see the text testmove123 in my browser.
Another example:
Javascript:
function download(file)
{
window.location=file;
}
+html:
<input type="button" value="Download" onClick="download('dateiupload/testmove.txt')" >
Makes the same.
Another example:
Javascript:
function download(path)
{
var ifrm = document.getElementById("frame");
ifrm.src = path;
}
+html:
<iframe id="frame" style="display:none"></iframe>
download
By clicking on "Download" the javascript function starts but nothing else happens and I see the same site.
Another example (with php):
Javascript:
function download(path)
{
var ifrm = document.getElementById(frame);
ifrm.src = "download.php?path="+path;
}
+html (same as above):
<iframe id="frame" style="display:none"></iframe>
download
+php (the reason my its more or less working):
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=".$_GET['path']);
readfile($_GET['path']);
This solution doesn't wait for a click from me and starts the download by starting the site.
A working solution I thought about would be to link to another site where the download automatically starts but its absolutely not how it have to be. I use $_POST variables on the site and I lose them when I leave the site and I can't come back after the download.
It must start the download by clicking on the filename.
You can download straight from the anchor tag by using the 'download' attribute.
<a href="dateiupload/testmove.txt" download>Download</a>
The filename of the downloaded file will be testmove.txt by default.
You can change the filename like this.
Download
More Details at w3Schools
You were correct to use those headers - as you can see, the file is being downloaded. The only problem now is to have it download when you want it to.
For a very simple solution, I would suggest setting up a download.php file that will be the page you download all files from. You would setup a GET parameter for this file and the URL would look something like this:
http://your-cool-site.com/download.php?filename=textmove.txt
Now inside download.php, you'll read that GET parameter which will be a filename, and then pass it eventually to the readfile function. This is the stage that you should think about enforcing some level of security as passing a path directly to the function could give people access to files that they shouldn't be looking at! Think about limiting the actual downloadable files to a limited selection of files or paths you know to be "safe" for people to download.
You'll also need to use the file name in the headers (and possibly even the size of the file to support displaying progress of the download).
Once you have this download.php file ready, you can place links to it from other pages in a very similar way that you have now:
Download File
Clicking on this link will make the request to download.php and when it gets the appropriate headers, the download will start.

detecting Download file dialog?

is there any way i could detect opening of download file dialog box on web pages like hyperlink click event occurs and download file dialog box appears.... ??
and can i edit the filename in it ...... like attaching some website name along with filename .... so when the user download any file it automatically rename in to website-filename.pdf etc pro-grammatically
can we use input tag for it ?? or have to make customcontrols for it ??
thanks if any help provided
take care.
regards,
newbiefreak
You can just make a hyperlink with its href to a regular file, your browser will prompt to download it.
As for renaming the file, all you could do is create a special page which sends the file contents and correct headers, and specifying another name. You'll have to send the content-disposition header, as such:
Content-disposition: attachment; filename=yourfilename.extension
You can send a Content-disposition header to force a file downlaod box and specify a default filename.
http://support.microsoft.com/kb/260519
In regards to editing the filename:
HTML5 introduces a new attribute for a tags: download.
Using it forces browsers that support the attribute to prompt for a file download, rather than navigating to or attempting to open the linked file.
Also, whatever you value you assign to download will replace the file's actual name.
Source and demo: http://updates.html5rocks.com/2011/08/Downloading-resources-in-HTML5-a-download

Categories