浏览器的千年难题:用户上传了新头像,但其他人包括他自己死活看不到
我们论坛的头像上传后,提示已经更新成功。其实也真的是已经成功。
但用户看到的,仍然是旧头像。
其他人看到的,也极可能是旧头像。
除非:其它人之前没有打开过用户的头像,或大家将浏览器的缓存清理一次。
浏览器这个属于非常操蛋的设计:只要文件名一样,就算日期不一样、文件大小不一样,浏览器都不会再去刷新。
于是导致了以上问题的产生。
现在已经是2020年了,浏览器还没法解决这个问题?
其实解决思路很简单:判断文件日期,如果目前网页上的日期,比缓存里面的还要新,就刷新这个文件。
有人知道这个问题是解决办法?
如果没有解决办法,我只能让技术人员修改论坛代码,让每次上传用户头像后,文件名里面加入随机数,强制改名为其他文件名。
设置缓存失效时间就可以了。以nginx为例:
location ~ .*\.(jpg|jpeg|png|bmp)$
{
expires max;
access_log off;
log_not_found off;
add_header Vary Accept;
add_header Pragma public;
add_header Cache-Control "public";
}
里面
expires max; 表示缓存长期有效
将其更改为
expires 1d; 表示缓存1天有效
本帖最后由 sunnyqd 于 2020-7-25 10:02 编辑
另外,
add_header Pragma public;
add_header Cache-Control "public";
两句表示文件可以被代理服务器缓存,将其更改为
add_header Pragma private;
add_header Cache-Control "private";
表示文件仅可被用户浏览器缓存,不能被代理服务器缓存
上述是nginx的设置,对于其他服务器也有对应的设置
为了提高效率,可以将头像文件专门设置一个location块,将头像的缓存时间设置为1h。
如下是服务器返回的响应头,更改服务器端的设置,就可以告诉浏览器和代理服务器这些文件的有效时间是多少:
sunnyqd 发表于 2020-7-25 09:50
设置缓存失效时间就可以了。以nginx为例:
location ~ .*\.(jpg|jpeg|png|bmp)$
{
这个方法有个问题:
expires 1d; 表示缓存1天有效
用户自己上传头像后,还要1天后才能看到变化?
就算可以设置到0天,即完全不适应缓存,那用户每次打开同一个帖子,所有图片都要重新下载一次?
缓存的问题,在论坛的帖子里不明显,因为重新上传的图片,名字也会不一样。
只有头像更新,文件名还是一样。所以,如果浏览器要做到这样才可以解决问题:判断文件的日期,如果比缓存的新,就重新下载。
如果浏览器做不到,我认为修改论坛系统,让每一次上传的头像,文件名都不一样。 只能修改文件名了。 armok. 发表于 2020-7-25 10:00
这个方法有个问题:
expires 1d; 表示缓存1天有效
“如果浏览器要做到这样才可以解决问题:判断文件的日期,如果比缓存的新,就重新下载”,----现代浏览器可以做到的
浏览器的缓存机制分为强制缓存和协商缓存
浏览器优先使用强制缓存,强制缓存通过我上面说的缓存时间来指定,在有效缓存时间内的,浏览器认为该文件是强制缓存,不与服务器通讯,直接采用该缓存。
若浏览器判断强制缓存无效(如时间超出,或者文件头有 Cache-Control:no-cache; 标识),则浏览器向服务器发送请求头,其中包含Etag信息;服务器收到浏览器的请求头后,会判别浏览器发送的Etag信息是否与当前文件的Etag相符,
若相符,则服务器仅发回304响应,告诉浏览器该文件未更新,则浏览器便采用缓存的文件,并不重新下载;若服务器判别Etag不相符,则返回200响应,包含最新的文件内容,浏览器便接收最新文件。
所以,如果要实现这种功能的话,将头像文件的文件夹里的图片,设置为expires 60s; 比较合适,缓存超时后会自动采用协商缓存的过程。
仅设置头像文件夹图片就可以了,其他图片可以保留原有设置,无影响。
把头像展示的img标签代码改改,加上用户更新的时间戳,譬如原来是 ....a.jpg 改成 ....a.jpg?t=1576352738 yplin27 发表于 2020-7-25 10:31
把头像展示的img标签代码改改,加上用户更新的时间戳,譬如原来是 ....a.jpg 改成 ....a.jpg?t=1576352738 ...
哈哈,这是个好主意。论坛验证码就是这样做的,关键是代价=0 yplin27 发表于 2020-7-25 10:31
把头像展示的img标签代码改改,加上用户更新的时间戳,譬如原来是 ....a.jpg 改成 ....a.jpg?t=1576352738 ...
但这个方法有个缺陷:每一次浏览器都必须重新读入头像。浪费流量。 sunnyqd 发表于 2020-7-25 10:29
“如果浏览器要做到这样才可以解决问题:判断文件的日期,如果比缓存的新,就重新下载”,----现代浏览器 ...
1。太依赖浏览器。
2。上传后,60s后才能让本人看到,也是不可接受的。
3。还要解决其他99.99%真的不需要再重新读入的头像问题。重复读入会浪费流量。 还是回到刚才的结论:
浏览器要做到这样才可以解决问题:判断文件的日期,如果比缓存的新,就重新下载。
如果浏览器做不到,我认为修改论坛系统,让每一次上传的头像,文件名都不一样。 armok. 发表于 2020-7-25 10:59
但这个方法有个缺陷:每一次浏览器都必须重新读入头像。浪费流量。
不用啊。数据库加一个上传计数不就完事了。这样就是t=1,t=2之类了,不是随机数就不用读。 wye11083 发表于 2020-7-25 11:14
不用啊。数据库加一个上传计数不就完事了。这样就是t=1,t=2之类了,不是随机数就不用读。 ...
那你这种做法,远远比上传头像的时候,就改文件名简单了。 armok. 发表于 2020-7-25 10:59
但这个方法有个缺陷:每一次浏览器都必须重新读入头像。浪费流量。
时间戳是头像上传的时间(如果有保存的话),印象中这样浏览器也是会根据url缓存的 yplin27 发表于 2020-7-25 12:06
时间戳是头像上传的时间(如果有保存的话),印象中这样浏览器也是会根据url缓存的 ...
你这个可行。
jpg?t=上传时间。
上传时间如果系统没有记录,可以查找文件时间。 改名是最简单与有效的了 wuhuijiang 发表于 2020-7-25 12:11
改名是最简单与有效的了
是的,没有后遗症。 改名遇到技术困难,改成如下解决方案:
论坛功能更新通知:上传头像,增加清理浏览器缓存的提示教程
https://www.amobbs.com/thread-5737243-1-1.html
(出处: amobbs.com 阿莫电子论坛)
页:
[1]