0

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?

garydavenport73
  • 379
  • 2
  • 8
  • Make sure you sent the [Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#syntax) header at the php file too. – Christopher Jul 11 '22 at 01:17
  • Thank you Christopher for the comment, that was very helpful. I am answering my own question based on your helpful link. – garydavenport73 Jul 11 '22 at 16:26

1 Answers1

1

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.

  1. 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:

<a href="desiredpage.html" download="suggestedname.html">Click to download</a>

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.

  1. 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:

<a href="download.php">Click here to download</a>

Reference: Download Link not working in html

With useful comments from: Anirban and Christopher.

garydavenport73
  • 379
  • 2
  • 8