如何设置从浏览器下载的文件的名称?

我正在编写一个网络应用程序,其中,允许用户上传文件到我的服务器。为了防止名称冲突和组织文件,一旦它们被放到我的服务器上,我就重命名它们。通过跟踪原始文件名,我可以与文件的所有者沟通,而不会让他们知道我在后端改变了文件名。直到他们去下载文件。在这种情况下,系统会提示他们下载一个名称不熟悉的文件。

我的问题是,有没有办法只使用 HTML 来指定要下载的文件的名称?因此,用户上传一个名为“ abc.txt”的文件,我将其重命名为“ xyz.txt”,但是当他们下载该文件时,我希望浏览器默认将该文件保存为“ abc.txt”。如果仅仅使用 HTML 无法做到这一点,有什么方法可以做到吗?

121491 次浏览

Can't find a way in HTML. I think you'll need a server-side script which will output a content-disposition header. In php this is done like this:

header('Content-Disposition: attachment; filename="downloaded.pdf"');

if you wish to provide a default filename, but not automatic download, this seems to work.

header('Content-Disposition: inline; filename="filetodownload.jpg"');

In fact, it is the server that is directly serving your files, so you have no way to interact with it from HTML, as HTML is not involved at all.

Well, @Palantir's answer is, for me, the most correct way!

If you plan to use that with multiple files, then i suggest you to use (or make one) PHP Download Manager.

BUT, if you want to make that to one or two files, I will suggest you the mod_rewrite option:

You have to create or edit your .htaccess file on htdocs folder and add this:

RewriteEngine  on
RewriteRule ^abc\.txt$  xyz.txt

With this code, users will download xyz.txt data with the name abc.txt

NOTE: Verify if you have already the "RewriteEngine on " on your file, if yes, add only the second for each file you wish to redirect.

Good Luck ;) (Sorry for my english)

When they click a button to download the file, you can add the HTML5 attribute download where you can set the default filename.

That's what I did, when I created a xlsx file and the browser want to save it as zip file.

<a href="path/to/file" download="renamed.txt">Download</a>
<a href="downloads/export.xlsx" download="Data-Export.xlsx">Download Export</a>

just need to use HTML5 a tag download attribute

codepen live demo

https://codepen.io/xgqfrms/full/GyEGzG/

my screen shortcut.

enter image description here

enter image description here

update answer

  1. whether a file is downloadable depends on the server's response config, such as Content-Type, Content-Disposition;

  2. download file's extensions are optional, depending on the server's config, too.

'Content-Type': 'application/octet-stream',
// it means unknown binary file,
// browsers usually don't execute it, or even ask if it should be executed.


'Content-Disposition': `attachment; filename=server_filename.filetype`,
// if the header specifies a filename,
// it takes priority over a filename specified in the download attribute.

download blob url file

    function generatorBlobVideo(url, type, dom, link) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function(res) {
// console.log('res =', res);
var blob = new Blob(
[xhr.response],
{'type' : type},
);
// create blob url
var urlBlob = URL.createObjectURL(blob);
dom.src = urlBlob;
// download file using `a` tag
link.href = urlBlob;
};
xhr.send();
}


(function() {
var type = 'image/png';
var url = 'https://cdn.xgqfrms.xyz/logo/icon.png';
var dom = document.querySelector('#img');
var link = document.querySelector('#img-link');
generatorBlobVideo(url, type, dom, link);
})();

https://cdn.xgqfrms.xyz/HTML5/Blob/index.html

refs

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#download

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#important_mime_types_for_web_developers

Sometimes @Mephiztopheles answer won't work on blob storages and some browsers.

For this you need to use a custom function to convert the file to blob and download it

const coverntFiletoBlobAndDownload = async (file, name) => {
const blob = await fetch(file).then(r => r.blob())
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.style.display = 'none'
a.href = url
a.download = name // add custom extension here
document.body.appendChild(a)
a.click()
window.URL.revokeObjectURL(url)
}