0

我正在 NodeJS 中构建一个应用程序,它使用Knox S3 客户端将文件存储在 Amazon S3 中。一切都适用于上传文件,移动文件等。

现在我想使用查询字符串身份验证机制来允许直接下载文件。为此,我在 NodeJS 服务器上调用了一些代码来调用 Knox 库并创建一个签名的 url。

代码如下所示:


exports.getS3Policy = function(file) {
  var date = moment().add("min", 60).toDate();
  var expires = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),  date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());

  return knoxClient.signedUrl(file, expires);
};

此代码返回带有身份验证参数的正确 URL。例如:

https://my-bucket.s3.amazonaws.com/some/folder/file.ext?Expires=1234567890&AWSAccessKeyId=ABCDEFGHIJKLMNO&Signature=someEncodedSignature

根据我读过的所有文件,这是一个正确的 URL。这个网址我没有从亚马逊收到任何错误。过期是正确的(我可以通过创建 1 秒的过期然后得到过期错误来验证这一点)。文件路径也正确。

但是,当我在浏览器中点击 url 时,我的浏览器(OSX 上的最新 Chrome)取消了文件的下载,即使我收到了200 ok包含正确文件信息的响应。

这是来自 Chrome 开发工具的请求信息的副本(已替换敏感位):


Request URL:https://my-bucket.s3.amazonaws.com/some/folder/file.ext?Expires=1234567890&AWSAccessKeyId=ABCDEFGHIJKLMNO&Signature=someEncodedSignature
Request Method:GET
Status Code:200 OK
Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
DNT:1
Host:my-bucket.s3.amazonaws.com
Pragma:no-cache
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.65 Safari/537.36
Query String Parameters
Expires:1234567890
AWSAccessKeyId:ABCDEFGHIJKLMNO
Signature:someEncodedSignature
Response Headers
Accept-Ranges:bytes
Content-Length:341390
Content-Type:application/octet-stream
Date:Tue, 10 Sep 2013 13:22:55 GMT
ETag:"fc4d24e752097f212e111f2736af7162"
Last-Modified:Tue, 10 Sep 2013 01:40:31 GMT
Server:AmazonS3
x-amz-id-2:some-id
x-amz-request-id:some-request-id

如您所见,服务器响应为“200 ok”。content-length341390 也是我尝试下载的文件的正确长度 - 这是实际文件大小。我将内容类型设置为“application/octet-stream”,因为这就是我告诉 S3 存储文件的方式......我只想要原始下载,基本上。

但在收到 S3 的此响应后,Chrome 会取消下载。这是来自 devtools 的屏幕截图,再次:

FireFox 和 Safari 都按预期下载文件。为什么chrome取消下载?我究竟做错了什么?是内容类型吗?或者 ?

4

1 回答 1

1

当然,我一发布问题就会找到答案......这是Chrome中的一个错误

https://code.google.com/p/chromium/issues/detail?id=104331

该修复将从 Chrome/Chromium 30.x 开始提供。如果您在 Chrome 30 或更高版本中遇到类似问题,请打开一个新问题。

指示必须下载资源的受支持方法是使用 Content-Disposition 标头字段 ( https://www.rfc-editor.org/rfc/rfc6266 )。

看起来我必须让 S3content-disposition在响应中设置 a 。

于 2013-09-10T13:56:08.353 回答