防止浏览器缓存图片
Prevent browser from caching images
为了实现未经身份验证的用户无法仅通过猜测 URL 查看图像(例如 http://www.test.com/images/123.jpg
我将所有图像 存储在 public 目录之外 并提供一个 URL 接受图片的唯一 ID 并检查用户是否已通过身份验证:
// Laravel code behind http://www.test.com/image/5
public function getimage($uid) {
if(Auth::check()) {
$filename = Picture::findorfail($uid)->filename; // e. g. '123.jpg'
return response()->download(storage_path('images/' . $filename), null, [], null);
} else {
return response()->download('images/no_access.jpg', null, [], null);
}
}
因此,经过身份验证的用户会得到图像“123.jpg”,而未经身份验证的用户会得到图像 'no_access.jpg',它只是白色背景上的红色文本 'No access'。
一切正常,只要我在注销后手动硬清除浏览器缓存(Chrome 在我的例子中)。
但是如果
- 我通过
http://www.test.com/image/5
登录并访问图像,然后我得到图像“123.jpg”(正确到这里)
- 然后注销并再次调用
http://www.test.com/image/5
然后我应该得到 'no_access.jpg' 但由于浏览器缓存我得到受保护的图像 '123.jpg' (缓存覆盖授权检查)
我已经尝试 <meta http-equiv="expires" content="0">
但没有成功。 Agian,如果我硬清除缓存,一切都是完美的 - 但普通用户不会那样做。
如何告诉浏览器不要缓存?
提前致谢!
尝试在 url
的末尾放置一个随机变量
http://www.test.com/images/123.jpg?{{rand()}}
您可以阻止浏览器缓存图像,但您必须创建一个 .htaccess
文件并向其中添加以下内容:
<filesMatch "\.(jpg|png)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>
</filesMatch>
希望对您有所帮助:)
根据@CharlotteDunois 的想法,我做了一些测试,发现在 Laravel 5.3 中,以下内容适用于我所有的 use-cases:
return response()->download(
storage_path('images/' . $filename),
null,
[ 'Cache-Control' => 'no-cache, no-store, must-revalidate', 'Pragma' => 'no-cache', 'Expires' => '0' ],
null
);
第三个参数表示headers的集合。请注意将 header-name(例如 'Cache-Control')用作 array-key,将 header-value(例如 'no-cache')用作 array-value。互联网上有建议的解决方案说 ['Cache-Control: no-cache']
...那是错误的!你必须使用 ['Cache-Control' => 'no-cache']
。祝你好运。
感谢所有的输入!
为了实现未经身份验证的用户无法仅通过猜测 URL 查看图像(例如 http://www.test.com/images/123.jpg
我将所有图像 存储在 public 目录之外 并提供一个 URL 接受图片的唯一 ID 并检查用户是否已通过身份验证:
// Laravel code behind http://www.test.com/image/5
public function getimage($uid) {
if(Auth::check()) {
$filename = Picture::findorfail($uid)->filename; // e. g. '123.jpg'
return response()->download(storage_path('images/' . $filename), null, [], null);
} else {
return response()->download('images/no_access.jpg', null, [], null);
}
}
因此,经过身份验证的用户会得到图像“123.jpg”,而未经身份验证的用户会得到图像 'no_access.jpg',它只是白色背景上的红色文本 'No access'。
一切正常,只要我在注销后手动硬清除浏览器缓存(Chrome 在我的例子中)。
但是如果
- 我通过
http://www.test.com/image/5
登录并访问图像,然后我得到图像“123.jpg”(正确到这里) - 然后注销并再次调用
http://www.test.com/image/5
然后我应该得到 'no_access.jpg' 但由于浏览器缓存我得到受保护的图像 '123.jpg' (缓存覆盖授权检查)
我已经尝试 <meta http-equiv="expires" content="0">
但没有成功。 Agian,如果我硬清除缓存,一切都是完美的 - 但普通用户不会那样做。
如何告诉浏览器不要缓存?
提前致谢!
尝试在 url
的末尾放置一个随机变量http://www.test.com/images/123.jpg?{{rand()}}
您可以阻止浏览器缓存图像,但您必须创建一个 .htaccess
文件并向其中添加以下内容:
<filesMatch "\.(jpg|png)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>
</filesMatch>
希望对您有所帮助:)
根据@CharlotteDunois 的想法,我做了一些测试,发现在 Laravel 5.3 中,以下内容适用于我所有的 use-cases:
return response()->download(
storage_path('images/' . $filename),
null,
[ 'Cache-Control' => 'no-cache, no-store, must-revalidate', 'Pragma' => 'no-cache', 'Expires' => '0' ],
null
);
第三个参数表示headers的集合。请注意将 header-name(例如 'Cache-Control')用作 array-key,将 header-value(例如 'no-cache')用作 array-value。互联网上有建议的解决方案说 ['Cache-Control: no-cache']
...那是错误的!你必须使用 ['Cache-Control' => 'no-cache']
。祝你好运。
感谢所有的输入!