【问题标题】:How to download a file without using <a> element with download attribute or a server?如何在不使用具有下载属性或服务器的 <a> 元素的情况下下载文件?
【发布时间】:2016-12-07 07:10:03
【问题描述】:

根据caniuse&lt;a&gt;元素的download属性Microsoft Edge build 10547+支持,但not IE or Safari

如何在不使用带有download 属性集的&lt;a&gt; 元素或服务器的情况下下载文件对象?

【问题讨论】:

标签: javascript html file download fileapi


【解决方案1】:

有多种触发下载的方法。以下是一些:

使用表格:

<form method="get" action="mydoc.doc">
<button type="submit">Download</button>
</form>

使用javascript:

<button type="submit" onclick="window.open('mydoc.doc')">Download</button>

【讨论】:

  • 如果用户有打开 mydoc.doc 的浏览器插件怎么办?那么怎么下载呢?
  • 用户可以选择保存他们通过浏览器插件看到的内容。但是,您不能从前端强制下载。看到这个:stackoverflow.com/questions/8613725/…
【解决方案2】:

虽然我支持@LeoFarmer 的回答,但我想提供两种“可破解”的方法:

  1. 如果文件非常小,可以使用ahref='data:[&lt;mediatype&gt;][;base64],&lt;data&gt;'

    这可以让您在 mediatype 中添加内容处置,模拟 HTTP 标头。这种 hack 也没有人们希望的那么便携。

  2. 对于中小型文件,可以使用 AJAX 下载文件,然后use the Javascript File API to prompt for file saving(API 不支持保存,但很容易将数据转换为数据 URL)。

    如果您想避免使用 Javascript File API,可以尝试模拟锚点点击,如 suggested here

再一次,正如 Leo Farmer 所指出的,这些解决方案不能保证浏览器不会在新选项卡中打开文件而是将其保存到磁盘,但我认为可以肯定地说所有用户都会能够优雅地降级为cmd+Sctrl+S 键盘快捷键:-)

【讨论】:

    【解决方案3】:

    您可以同时使用下载属性和 jquery 来执行此操作。下载属性在 ie 和 safari/ios 中不支持。所以你可以使用 jquery 来做到这一点

     $('.download').click(function(e) {
        e.preventDefault();  //stop the browser from following
        window.location.href = 'uploads/file.doc';
    });
    
    <a href="no-script.html" class="download">Download</a>
    

    【讨论】:

      【解决方案4】:

      使用FileSaver.js

      它支持所有常用的浏览器。

      只需包括:

      <script type="text/javascript" src="FileSaver.min.js"></script>
      

      并像这样使用它:

      var file = new File(["Hello, world!"], "hello world.txt", {type: "text/plain;charset=utf-8"});
      saveAs(file);
      

      注意: 要使其在 Safari Blob.js 作为依赖项。

      【讨论】:

      • 答案最后一句提到的浏览器是否有File构造函数?
      • 不,他们没有。 (caniuse.com/#search=File) 但是看看 FileSaver.js 的文档,还有其他的保存方式。我希望你会发现它有帮助。 :)
      【解决方案5】:

      您可以使用data URIdata:[&lt;mediatype&gt;][;base64],&lt;data&gt; 表示文件,手动创建或使用FileReader().readAsDataURL(),将MIME 类型设置为application/octet-streamencodeURIComponent()window.open()

      <script>
        var file = "data:application/octet-stream,"
                   + encodeURIComponent("<!DOCTYPE html>"
                   + "<html><body>"
                   + "<div>abc</div>"
                   + "</body></html>");
        var saveFile = window.open(file, "_self");     
      </script>
      

      <script>
        var blob = new Blob(["abc"], {type:"text/plain"});
        var reader = new FileReader();
        reader.addEventListener("load", function(e) {
          // replace existing `MIME` type with `application/octet-stream`
          var file = "data:application/octet-stream;" 
                      + e.target.result.split(/;/)[1];
          var saveFile = window.open(file, "_self");
        });
        reader.readAsDataURL(blob)
      </script>
      

      plnkr http://plnkr.co/edit/IS1OC0laRwL3BuuF9zay?p=preview

      【讨论】:

        【解决方案6】:

        如果您使用的是服务器端,请按照表单提交机制来呈现页面。 在 MVC 中我们可以使用下面的代码

        HTML

          @using (Html.BeginForm("GetAttachment", "User", FormMethod.Post))
                        {
        
                            <button type="submit">Download</button>   
                        }
        

        MVC 控制器

        public ActionResult GetAttachment()
        {
           string filename = "File.pdf";
        string filepath = AppDomain.CurrentDomain.BaseDirectory + "/Path/To/File/" + filename;
        byte[] filedata = System.IO.File.ReadAllBytes(filepath);
        string contentType = MimeMapping.GetMimeMapping(filepath);
        
        var cd = new System.Net.Mime.ContentDisposition
        {
            FileName = filename,
            Inline = true,
        };
        
        Response.AppendHeader("Content-Disposition", cd.ToString());
        
        return File(filedata, contentType);
        }
        

        【讨论】:

        • "不使用带有下载属性的&lt;a&gt; 元素或服务器?"
        • 使用表单将数据提交到服务器,服务器返回文件。
        • &lt;form&gt; 不需要提交到服务器。 Question的要求是不使用服务器
        • 不确定您的意思?
        • 为什么需要 jQuery 插件?
        猜你喜欢
        • 2020-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-21
        相关资源
        最近更新 更多