Specify a name and file format if the file or file does not contain

I would like to indicate the file name and the format of the “atypical file” due to the lack of better words. Files are stored in places such as the following ...

let link = https://.../videoplayback?ipbits=0&initcwndb...D134213BA9465CB74DFD36CDE47BF.102638C4A9F3ACA357F79EE747DD5F49F1E0F0DE

When you download such files, even if they are completely different files, they always end up being saved with the same name and never expanding.

I tried url.download = link + '.mp4' , but this has no effect.

How can i do this?

+7
javascript file html5 download downloading
source share
3 answers

According to MDN for anchor tags with attribute download :

Can be used with blob: URLs and data: URLs to make it easier for users to download JavaScript-generated content (for example, an image created using an online graphics web application).

If the HTTP Content-Disposition: header is present and gives a different file name than this attribute, the HTTP header takes precedence over this attribute.

If this attribute is present and Content-Disposition: set to inline, Firefox prioritizes Content-Disposition, for example, for the filename case, while Chrome gives priority to the download attribute.

This attribute is only valid for resource references using the same origin.

So, if you dynamically generate these links, and they come from your own server - you can set the file name. Cross search query will not work!

You can use ajax to extract the file as a blob and cheat the browser, assuming that the data is not cross. See this answer for one possible implementation.

+6
source share

One approach is to execute a HEAD request before setting the .download property of the .download element to determine the Content-Type requested resource, use a JSON string, JavaScript object or other key, the value is a paired data storage format to reflect pairs of valid MIME types for valid file extensions matching the MIME property. Use .indexOf() , RegExp or another filtering method to determine if there is a match between the property name of the string or object and the property value if true stores the extension value and combines the extension with the proposed file name.

If the file does not serve with CORS headers, you can try using a proxy server to make a HEAD GET request to get the Content-Type header before setting the .download attribute.

It should be noted that the .download attribute is just a suggestion to the user to specify a file name. The user can change the file name at any time, including deleting the file extension, for some reason they may or may not have. Or do not load the resource at all.

 const mimeTypeExtensions = { "text/plain": ".txt", "video/mp4": ".mp4", /* valid MIME types and corresponding extensions */ } const a = document.querySelector("a"); a.addEventListener("click", event => { if (!a.download) { event.preventDefault(); fetch(a.href, {method: "HEAD"}) .then(response => { const mimeType = response.headers.get("content-type"); let fileExtension = ""; for (let [key, prop] of Object.entries(mimeTypeExtensions)) { if (key.indexOf(mimeType) > -1) { fileExtension = prop; break; }; } a.download = `filename${fileExtension}`; a.click(); }) .catch(err => console.error(err)) } }); 
 <a href="https://gist.githubusercontent.com/guest271314/11edc4566ba94f204dd46e6ae26edaad/raw/d118e99abbe2a2c60634e46816df9e1b9de6b6b8/D134213BA9465CB74DFD36CDE47BF102638C4A9F3ACA357F79EE747DD5F49F1E0F0DE">click</a> 
+3
source share

Here is a simple option if you do not mind adding a library. FileSaver.js does a good job of hiding these ugly details. I was going to understand how you can create a Blob, write the contents of the download to it, and then create a binding tag with the URL of the object created from Blob, but FileSaver handles this already, and you can look at the source if you really wanted to.

Just change the following to add some checks and logic to determine the file name / file type, and you can solve your use case.

 <script src="cdn-to-FileSaver.js"></script> <script> var url = ...; fetch(url).then((response) => { var blob = response.blob(); var filename = 'song.mp4'; saveAs(blob, filename); }); </script> 
+2
source share

All Articles