在 IE11 中从 Cloudfront 下载的可执行文件 (Windows 7) 不带文件扩展名的下载
Executable downloaded from Cloudfront in IE11 (Windows 7) downloads without a file extension
它的 long-short 是 .exe
从 Cloudfront 下载的 IE11/Win7 次下载(使用签名 URL),没有扩展名 (exe_file.exe -> exe_file
)
我不认为这与描述的问题相同here(在许多其他地方)因为文件没有重命名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/something 在某些时候会尝试进行一些智能 MIME 分配(另外,之前,当我在没有该参数的情况下上传,检查下载 headers 将显示正确的 MIME 类型)。
Headers 下载文件时收到
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.dmg
和 linux_file.zip
都与扩展一起下载。其他浏览器也不受影响——它们都在 S3.
中下载文件 as-is
我已经尝试过使用和不使用 AV - 这没有区别。
您需要正确设置content-disposition
:
使用 HTTP header 强制 SaveAs
为了强制浏览器在单击超链接时显示 SaveAs 对话框,您必须在要下载的文件的 HTTP 响应中包含以下 header:
Content-Disposition: attachment; filename="<file name.ext>"; filename*=utf-8''<file name.ext>
注意:那些不支持 RFC 5987 编码的用户代理会忽略出现在 filename.
之后的 filename*
您希望在“另存为”对话框中显示的文件名在哪里(如 finances.xls 或 mortgage.pdf)- 不带 <
和 >
符号。
您必须牢记以下几点:
- 文件名应采用 US-ASCII 字符集且不应包含特殊字符:
< > \ " / : | ? *
space.
- 文件名不应指定任何目录路径信息。
- 文件名应包含在双引号中,但大多数浏览器将支持不带双引号的文件名。
古代浏览器还需要以下内容(现在不需要,但对于万无一失的解决方案可能值得这样做):
- Content-Type header 应该在 Content-Disposition.
之前
- Content-Type header 应该引用未知的 MIME 类型(至少在旧浏览器消失之前)。
所以,您应该使用 cp
和选项:
--content-type (string)
为此操作指定明确的内容类型。此值覆盖任何猜测的 MIME 类型。
--content-disposition (string)
指定 object. 的展示信息
--metadata-directive REPLACE
指定元数据是从源 object 复制还是替换为复制 S3 objects 时提供的元数据。
请注意,如果您使用以下任何参数:--content-type
、content-language
、--content-encoding
、--content-disposition
、--cache-control
或 --expires
,如果您希望复制的 object 具有指定的元数据值,则需要为 non-multipart 个副本指定 --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 Signer 提供了自己的 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'
})
它的 long-short 是 .exe
从 Cloudfront 下载的 IE11/Win7 次下载(使用签名 URL),没有扩展名 (exe_file.exe -> exe_file
)
我不认为这与描述的问题相同here(在许多其他地方)因为文件没有重命名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/something 在某些时候会尝试进行一些智能 MIME 分配(另外,之前,当我在没有该参数的情况下上传,检查下载 headers 将显示正确的 MIME 类型)。
Headers 下载文件时收到
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.dmg
和 linux_file.zip
都与扩展一起下载。其他浏览器也不受影响——它们都在 S3.
我已经尝试过使用和不使用 AV - 这没有区别。
您需要正确设置content-disposition
:
使用 HTTP header 强制 SaveAs 为了强制浏览器在单击超链接时显示 SaveAs 对话框,您必须在要下载的文件的 HTTP 响应中包含以下 header:
Content-Disposition: attachment; filename="<file name.ext>"; filename*=utf-8''<file name.ext>
注意:那些不支持 RFC 5987 编码的用户代理会忽略出现在 filename.
之后的filename*
您希望在“另存为”对话框中显示的文件名在哪里(如 finances.xls 或 mortgage.pdf)- 不带 <
和 >
符号。
您必须牢记以下几点:
- 文件名应采用 US-ASCII 字符集且不应包含特殊字符:
< > \ " / : | ? *
space. - 文件名不应指定任何目录路径信息。
- 文件名应包含在双引号中,但大多数浏览器将支持不带双引号的文件名。
古代浏览器还需要以下内容(现在不需要,但对于万无一失的解决方案可能值得这样做):
- Content-Type header 应该在 Content-Disposition. 之前
- Content-Type header 应该引用未知的 MIME 类型(至少在旧浏览器消失之前)。
所以,您应该使用 cp
和选项:
--content-type (string)
为此操作指定明确的内容类型。此值覆盖任何猜测的 MIME 类型。--content-disposition (string)
指定 object. 的展示信息
--metadata-directive REPLACE
指定元数据是从源 object 复制还是替换为复制 S3 objects 时提供的元数据。
请注意,如果您使用以下任何参数:--content-type
、content-language
、--content-encoding
、--content-disposition
、--cache-control
或 --expires
,如果您希望复制的 object 具有指定的元数据值,则需要为 non-multipart 个副本指定 --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 Signer 提供了自己的 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'
})