【问题标题】:Download file without displaying URL下载文件而不显示 URL
【发布时间】:2017-10-09 04:44:42
【问题描述】:

故事

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

要求

有两个要求

  1. 下载时更改文件名。
  2. 从前端隐藏文件 url - 视图。

努力

Effort-1:使用锚标签

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

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

这会下载文件,但由于某些原因不会更改名称。修改了很多次都解决不了。

Effort-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 文件 不向用户显示 URL 并在下载时更改文件名?

【问题讨论】:

    标签: jquery ajax excel amazon-s3


    【解决方案1】:

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

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

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

    选项 1。

    当您将文件上传到 S3 时,发送该标头。 S3 将在每次下载时返回它,并且浏览器将使用该文件名。

    选项 2。

    在您签名的 URL 中,告诉 S3 将此标头添加到响应中。这会将&amp;response-content-disposition=attac... 添加到签名的 URL 中,S3 将看到这一点并添加所需的响应标头。

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

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

    当然...如果您没有使用预签名 URL,那么这就是您遇到的真正问题...隐藏 URL 只是尝试解决错误问题.任何最低限度的复杂用户都可以确定 URL,我断言尝试隐藏它不会获得真正的安全优势。

    【讨论】:

      【解决方案2】:

      它不是那样工作的。你下载了一些东西,请求的客户端知道它来自哪里。如果您想让该链接仅可使用一次或供特定人员使用,则需要通过您的应用程序服务器对其进行流式传输。

      唯一的其他解决方案是在 S3 级别创建用户/权限,但即便如此,URL 也会在某些时候显示。

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

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

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

      【讨论】:

      • 我不会在每次下载时更改文件名。它只是保存在 s3 上的那个文件有 unqiue 随机名称。所以下载后应该改回原来的名字。
      • 如果是单下载单上传,可以尝试使用S3 SDK更改文件名。请看这里:docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html 如果您正在使用它,请检查此处可能引发的安全问题。但是,我仍然认为您应该将这一切隐藏在您自己的服务器后面。如果不可能,请检查 JS SDK 的重命名功能。
      • 使用您的域的 cname 将该 cname 绑定到您的 s3 存储桶。无需隐藏任何东西。
      猜你喜欢
      • 2014-11-21
      • 2017-01-27
      • 2013-12-26
      • 2023-03-25
      • 2018-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-20
      相关资源
      最近更新 更多