在IE11(Windows 7)中从Cloudfront下载的可执行文件无需文件扩展名即可下载

其中的很长一段时间是在IE11 / Win7下载中从Cloudfront(使用签名的URL)下载的.exe ,没有扩展名( exe_file.exe -> exe_file

认为这是同样的问题(在许多其他地方),因为该文件没有被重命名为exe_file_exe ,扩展名只是被丢弃。

该文件由S3的Cloudfront提供 – 通过aws-cli上传

 $ aws s3 cp exe_file.exe s3://cdn/exe_file.exe --content-type "application/x-msdownload" 

据我所知, content-type参数不是绝对必要的作为CF / S3 /东西,在某种程度上,试图做一些智能MIME分配(加,之前,当我没有这个arg上传,检查下载标题将显示正确的MIMEtypes)。

下载文件时收到的标题

 HTTP/1.1 200 OK Content-Type: application/x-msdownload Content-Length: 69538768 Connection: keep-alive Date: Tue, 27 Dec 2016 17:36:51 GMT Last-Modified: Thu, 22 Dec 2016 22:31:59 GMT ETag: "c8fc68a920e198dca95e5549f8657bfb" Accept-Ranges: bytes Server: AmazonS3 Age: 335 X-Cache: Hit from cloudfront 

这只发生在Windows 7上的IE11 – 它在IE11 / Windows 10上工作正常(我只说,但我还没有尝试,例如,IE8 – 你不能付我足够的钱,让我自己通过)。 而其他下载则不会发生 – dmg_file.dmglinux_file.zip都是以扩展名下载的。 其他浏览器也不会受到影响 – 它们都是在S3中按原样下载文件。

我尝试过和没有AV礼物 – 这没有什么差别。

您需要正确设置content-disposition

使用HTTP标题强制SaveAs为了强制浏览器在单击超链接时显示SaveAs对话框,必须在要下载的文件的HTTP响应中包含以下标题:

 Content-Disposition: attachment; filename="<file name.ext>"; filename*=utf-8''<file name.ext> 

注意:那些不支持RFC 5987编码的用户代理在文件名后面忽略filename*

你想要在SaveAs对话框中显示的文件名在哪里(如finances.xls或mortgage.pdf) – 没有<>符号。

你必须牢记以下几点:

  1. 文件名应该是US-ASCII字符集,不应该包含特殊字符: < > \ " / : | ? *空格。
  2. 该文件名不应该有任何指定的目录路径信息。
  3. 文件名应该用双引号括起来,但大多数浏览器都会支持没有双引号的文件名。

古代的浏览器也需要以下(现在不需要,但是对于一个傻瓜式的解决方案来说可能是值得的):

  1. 内容类型标题应该在Content-Disposition之前。
  2. Content-Type头应该引用一个未知的MIME类型(至少在旧的浏览器消失之前)。

所以,你应该使用cp选项:

  1. --content-type (string)为此操作指定显式内容类型。 此值将覆盖任何猜测的MIME类型。
  2. --content-disposition (string)指定对象的表示信息。
  3. --metadata-directive REPLACE指定元数据是从源对象复制还是用复制S3对象时提供的元数据替换。

请注意,如果您正在使用以下任何参数:– --content-typecontent-language ,– --content-encoding ,– --content-disposition ,– --cache-control--expires ,则需要指定--metadata-directive REPLACE如果希望复制的对象具有指定的元数据值,则对非多部分副本进行--metadata-directive REPLACE

尝试:

 aws s3 cp exe_file.exe s3://cdn/exe_file.exe --content-type "application/x-msdownload" --content-disposition "attachment; filename=\"exe_file.exe\"; filename*=utf-8''exe_file.exe" --metadata-directive REPLACE 

除了接受的答案之外,我还向Cloudfront签名者提供了自己的response-content-disposition参数:

在Python中,它看起来像

 from botocore.signers import CloudFrontSigner def generate_presigned_url(filename, headers={}): cf_signer = CloudFrontSigner(CF_KEY_ID, rsa_signer) headers = '&'.join(["%s=%s" % (key, urllib.quote_plus(value)) for key, value in headers.iteritems()]) return cf_signer.generate_presigned_url( 'https://' + CF_DOMAIN + '/' + filename + ("" if len(headers) == 0 else "?%s" % (headers)), # ... other params ) 

叫使用

 cloudfront.generate_presigned_url(file_name, { 'response-content-disposition': 'attachment; filename="exe_file.exe"; filename*=utf-8\'\'exe_file.exe' })