Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Http 如何确保我的用户正在下载S3文件的新版本?_Http_Caching_Amazon S3_Etag - Fatal编程技术网

Http 如何确保我的用户正在下载S3文件的新版本?

Http 如何确保我的用户正在下载S3文件的新版本?,http,caching,amazon-s3,etag,Http,Caching,Amazon S3,Etag,这在bash文件中: s3cmd --add-header='Content-Encoding':'gzip' put /home/media/main.js s3://myproject/media/main.js 这就是我将主干压缩文件上传到AmazonS3的方法。 每次更改javascript文件时,我都会运行此命令 然而,当我在Chrome中刷新页面时,Chrome仍然使用缓存版本 请求标头: Accept:*/* Accept-Encoding:gzip, deflate, sdch

这在bash文件中:

s3cmd --add-header='Content-Encoding':'gzip' put /home/media/main.js s3://myproject/media/main.js
这就是我将主干压缩文件上传到AmazonS3的方法。 每次更改javascript文件时,我都会运行此命令

然而,当我在Chrome中刷新页面时,Chrome仍然使用缓存版本

请求标头:

Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,es;q=0.6
AlexaToolbar-ALX_NS_PH:AlexaToolbar/alxg-3.3
Cache-Control:max-age=0
Connection:keep-alive
Host:myproject.s3.amazonaws.com
If-Modified-Since:Thu, 04 Dec 2014 09:21:46 GMT
If-None-Match:"5ecfa32f291330156189f17b8945a6e3"
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
响应标题:

Accept-Ranges:bytes
Content-Encoding:gzip
Content-Length:70975
Content-Type:application/javascript
Date:Thu, 04 Dec 2014 09:50:06 GMT
ETag:"85041deb28328883dd88ff761b10ece4"
Last-Modified:Thu, 04 Dec 2014 09:50:01 GMT
Server:AmazonS3
x-amz-id-2:4fGKhKO8ZQowKIIFIMXgUo7OYEusZzSX4gXgp5cPzDyaUGcwY0h7BTAW4Xi4Gci0Pu2KXQ8=
x-amz-request-id:5374BDB48F85796

请注意,Etag是不同的。我对它进行了更改,但当我刷新页面时,我得到的就是这些。Chrome仍在使用我的旧文件。

看起来您的脚本已经被Chrome本身或其他临时服务器主动缓存

如果它是一个从HTML页面调用的js文件(听起来像),我见过的一种技术是让页面向文件添加一个参数:

<script src="/media/main.js?v=123"></script>
s3cmd --add-header="cache-control:max-age=0,no-cache" put file s3://your_bucket/


。。。在JS更新时更改(但服务器将忽略)。浏览器或任何临时缓存服务器都不会将其识别为相同的,因此不会尝试使用缓存的版本,即使在S3服务器上它仍然是相同的文件名

无论何时发布,都可以更新此编号/日期/任何内容,如果模板引擎可以访问应用程序的发布编号或id,则最好是自动更新

这不是最优雅的解决方案,但如果您发现自己使用了乐观的长缓存持续时间,那么拥有它是非常有用的

显然,只有将新文件正确上传到S3并且S3真正发送了新版本的文件时,这才有效。如果您对此有任何疑问,请尝试在javascript的url上使用命令行实用程序,如
curl
wget
,检查是否存在这种情况

失效方法 这将使指定文件的缓存无效。也有可能使整个站点无效,但是,上面的命令显示了在这种情况下您可能需要的内容

注意:每月前1000个请求是免费的。在此之后,每个文件的成本大约为0.005美元,因此,如果执行大量无效请求,这可能会引起关注

查询字符串/对象键方法 在缓存对象时,CloudFront包含来自给定URL的查询字符串(位于源位置)。这意味着,即使复制了相同的对象,但查询字符串不同,那么每个字符串都将作为不同的对象缓存。为了使其正常工作,当您使用CloudFront API时,需要在CloudFront控制台中为
转发查询字符串
选择
Yes
,或为
DistributionConfig复杂类型
中的
QueryString元素
的值指定
true

示例

http://myproject/media/main.js?parameter1=a
摘要

http://myproject/media/main.js?parameter1=a

确保所服务对象的最方便的方法是当前的willbeinvalidation,尽管如果您不介意管理查询字符串参数,那么您应该发现它同样有效。在我看来,调整标题不会像上面任何一种方法那样可靠;客户端以太多不同的方式处理缓存,因此很难区分缓存问题的位置。

您需要来自S3的响应来包含缓存控制头。您可以在上载文件时设置:

<script src="/media/main.js?v=123"></script>
s3cmd --add-header="cache-control:max-age=0,no-cache" put file s3://your_bucket/
在我的示例中,缺少空格和大写是由于s3cmd存在一些奇怪的签名问题。您的里程可能会有所不同


使用该命令更新文件后,您应该在S3响应中获得缓存控制头。

是否有方法在将JavaScript文件上载到服务器后修改它?如果可能的话,在其末尾添加一个返回码或空格将触发服务器完全识别更改并为新版本提供服务。您是否在S3前面使用Cloudfront或其他CDN类型的服务?我相信默认设置已经是
max age=0
——基于原始文件中发布的响应头问题,我不认为Cloudfront在这个场景中被使用。在我看来,请求是直接向S3发出的。