下载文件而不显示URL

时间:2017-05-10 13:35:51

标签: jquery ajax excel amazon-s3

故事

我有锚标记显示文件名,点击时用于从S3网址下载文件。我的客户端现在要求我隐藏URL并在下载文件时不显示它,并在S3上使用唯一名称而不是可读文件名。下载时,需要将文件名更改为上载时指定的可读文件名。

要求

有2个要求

  1. 下载时更改文件名。
  2. 隐藏前端的文件网址 - 查看。
  3. 努力

    努力1:使用锚标记

    最简单的解决方案是创建临时锚标记并在该锚标记中使用download属性。

    <a id="2135"></a>
    <script>
    function download(event) {
        var fileData = getFileData(event);
        var tempAnch = $('a').attr({href: fileData.url, download: fileData.name});
        tempAnch.click();
        tempAnch.remove();
    };
    </script>
    

    这会下载文件但由于某些原因不会更改名称。经过多次改动后我无法解决。

    努力2:使用Ajax方法

    现在我尝试在JS端下载文件内容并将其保存到文件中。

    $.ajax({
            type: 'GET',
            url: fileData.url,
            dataType: 'text',
            success: function(msg) {
                var blob = new Blob([msg],
                        {type: fileData.mimeType});
                saveAs(blob, fileData.name);
            }
        });
    

    现在,此代码保存了具有所需名称的文件,并且文本文件的内容相同。但是对于Excel文件或xlsx文件,下载的文件已损坏。

    是否有任何可能的解决方案可以下载xlsx,csv,txt或zip文件,而显示用户的网址,更改文件名下载?

2 个答案:

答案 0 :(得分:0)

这不是那样的。您下载了一些东西,请求客户端知道它来自哪里。如果您想使链接只能使用一次或者对于特定的人,则需要通过应用程序服务器对其进行流式处理。

唯一的其他解决方案是在S3级别创建用户/权限,但即使这样,URL也会在某个时刻显示。

我不建议在每次下载时更改文件名。

也就是说,安装自己的网络服务器,创建下载密钥,然后让用户调用您的网址。根据要求,您可以传递文件并使密钥无效。

请注意,如果下载需要很长时间才能完成,通常会阻止您的网络服务器上的资源。示例1和1中的廉价PHP托管需要超过10个并发用户的工作(我试过: - ))

答案 1 :(得分:0)

尽管这个要求很荒谬,但是当你在本地保存文件时,这就是告诉浏览器如何调用它正在下载的文件:你需要S3来添加这个响应标题:

Content-Disposition: attachment; filename="the-desired-name.ext"

这可以通过两种方式完成:

选项1。

将文件上传到S3时,请发送该标头。每次下载时S3都会返回它,浏览器将使用该文件名。

选项2。

在您签名的网址中,告诉S3将此标头添加到响应中。这会将&response-content-disposition=attac...添加到已签名的URL,S3将看到此内容并添加所需的响应标头。

如何执行此操作取决于您用于生成预签名URL的内容(即哪个SDK,或者如果您编写自己的SDK,就像我一样)。

此外,在生成预签名网址时,还有一个鲜为人知的功能,可让您在网址中找到您提供签名网址的对象。由于在不完全使URL无效的情况下无法更改或篡改已签名的URL,因此不鼓励用户“共享”他们可能发现的URL,因为URL会识别它们。 :)这是怎么做到的?您在签名前将x-amz-meta-{anything}={anything-else}添加到网址。示例:...&x-amz-meta-downloaded-by=michael-sqlbot&...。验证URL的S3部分将要求存在这些参数,以便URL与签名匹配,但实际返回正在下载的内容的S3部分将忽略它。

当然......如果您没有使用预先签名的网址,那么这就是您拥有的真正的问题......隐藏网址只是为了解决错误的问题。任何最低级别的用户都可以确定URL,并且我会声称通过尝试隐藏它无法实现真正​​的安全性好处。