如果文件或文件位置都不包含,请设置文件名和格式

时间:2017-07-26 03:11:38

标签: javascript html5 file download downloading

我想设置"非典型文件"的文件名和格式,因为缺少更好的单词。这些文件存储在以下位置......

dict

当下载这些文件时,即使它们是完全不同的文件,它们也总是以相同的名称保存,而不是文件扩展名。

我已经尝试了let link = https://.../videoplayback?ipbits=0&initcwndb...D134213BA9465CB74DFD36CDE47BF.102638C4A9F3ACA357F79EE747DD5F49F1E0F0DE,但这没有任何效果。

我该怎么做?

3 个答案:

答案 0 :(得分:6)

根据带有下载属性的anchor tags的MDN:

  

可与blob:URL和数据:URL一起使用,以方便用户使用   下载使用编程生成的内容   JavaScript(例如使用在线绘图Web应用程序创建的图片)。

     

如果HTTP标头Content-Disposition:存在并给出了   与此属性不同的文件名,HTTP标头具有优先级   超过这个属性。

     

如果此属性存在且Content-Disposition:设置为   在内联方面,Firefox优先考虑Content-Disposition,就像   文件名大小写,而Chrome则优先考虑下载属性。

     

此属性仅适用于带有的资源的链接   的同源。

因此,如果您动态生成这些链接并且它们来自您自己的服务器 - 您可以设置文件名。 跨源请求无效!

您可以使用ajax将文件作为blob获取,并诱使浏览器认为数据不是跨源的。有关一种可能的实现,请参阅this answer

答案 1 :(得分:3)

一种方法是在设置HEAD元素的.download属性之前执行<a>请求以确定所请求资源的Content-Type,使用JSON }字符串,JavaScript对象或其他键,值对数据存储格式,用于将有效MIME类型对与有效MIME类型属性的文件扩展名相对应。使用.indexOf()RegExp或其他过滤方法来确定字符串或对象的属性名称与属性值之间是否匹配,如果为true则存储扩展名值并将扩展名连接到建议的文件名。

如果文件未使用CORS标头提供,您可以尝试使用代理在HEAD GET之前获取Content-Type标头,然后再设置.download属性

应该注意,.download属性仅是用户对文件名的建议。用户可以随时更改文件的名称,包括删除文件扩展名,无论他们可能有或没有这些原因。或者根本不下载资源。

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>

答案 2 :(得分:2)

如果您不介意添加库,这是一个简单的选项。 FileSaver.js可以很好地处理这些情况,同时隐藏丑陋的细节。我将介绍如何创建Blob,将下载内容写入其中,然后创建一个带有从Blob创建的对象URL的锚标记,但FileSaver已经处理过,如果你可以查看源代码真的很想。

只需修改以下内容即可添加一些检查和逻辑来确定文件名/文件类型,您应该能够处理用例。

<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>