iT邦幫忙

0

快取問題

這個問題可折煞小弟了...
狀況是
目前使用者會上傳圖片到另外一台主機 而不是本地端的主機
但當使用者改變那張圖片的時候
圖片還是舊的
就算刪掉了 圖片還是能顯示出舊的
我明白這是快取問題
所以做了幾個處理
1.讓圖片每次都更新
我在圖片後面強制加上timestamp當參數
強迫圖片每次回傳都是新的

<img width="320px" src="<?php echo $ra[main_pic_src]."?".time();?>" alt="目前無圖">

可是由於是遠端傳回來的圖片
好像沒辦法躲掉 proxy的快取(??) 這是我的猜測

2.html 中 head加入防止快取
也就是常見的

<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="0">
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">

3.程式開始前PHP防止快取
加上這一大段 也是常見的方法

header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
session_start();
session_cache_limiter('private');
session_cache_expire(0);

但好像後面的方法也不起什麼作用
https://ithelp.ithome.com.tw/upload/images/20191227/20123565CjrqQUwjj2.jpg
回傳的圖片general長這樣
https://ithelp.ithome.com.tw/upload/images/20191227/20123565hkksNZVmrj.jpg
回傳的圖片response長這樣
last-modified的時間很明顯沒有刷新(時間都快4小時是正常的 系統部門設定的)
X-cache還是hit的到

大概要等20分鐘左右才會自動刷新
不知道是不是我哪裡處理上有問題
如果真的是Proxy的快取問題
我想請問各位大大有什麼方法關掉它嗎?或強迫它傳回的圖片更新

看更多先前的討論...收起先前的討論...
ccutmis iT邦高手 8 級 ‧ 2019-12-27 14:38:42 檢舉
https://stackoverflow.com/questions/8749434/how-to-prevent-browser-image-caching?rq=1

."?".time();
改成
."?t=" . time();
試試看
st474ddr iT邦新手 5 級 ‧ 2019-12-27 14:45:45 檢舉
還是一樣QQ
不會刷新
ccutmis iT邦高手 8 級 ‧ 2019-12-27 14:55:38 檢舉
你的 $ra[main_pic_src] 是長怎樣的?
st474ddr iT邦新手 5 級 ‧ 2019-12-27 14:59:12 檢舉
網址連結的方式
https://XXX.com/image/2019.jpg
dragonH iT邦超人 6 級 ‧ 2019-12-27 15:03:19 檢舉
你看一下你 browser 取回來的 image url 長怎樣
st474ddr iT邦新手 5 級 ‧ 2019-12-27 15:08:29 檢舉
我有補貼圖片在文章中了
fillano iT邦超人 1 級 ‧ 2019-12-27 15:51:11 檢舉
HiNetCDN/1908?

另外,在html或php裡面設定的cache相關header,跟html裡面使用到的image沒關係。靜態檔案一般是在伺服器設定cache policy。
st474ddr iT邦新手 5 級 ‧ 2019-12-27 17:48:05 檢舉
HiNetCDN/1908?
是伺服器

感謝大大 我研究研究

2 個回答

1
ccutmis
iT邦高手 8 級 ‧ 2019-12-27 16:03:31
最佳解答

如果不介意增加伺服器負擔的話,可以試試...

新增一個php檔 showimg.php

<?php
$imgUrl=$_SERVER['QUERY_STRING'];
if(strpos($imgUrl,'.png')>-1||strpos($imgUrl,'.PNG')>-1){
	header('Content-type: image/png');
}else if(strpos($imgUrl,'.jpg')>-1||strpos($imgUrl,'.JPG')>-1){
	header('Content-type: image/jpeg');
}else{
	header('Content-type: image/gif');
}
	echo file_get_contents($_SERVER['QUERY_STRING'].'?t='.time());
?>

然後把你原本的

<img width="320px" src="<?php echo $ra[main_pic_src]."?".time();?>" alt="目前無圖">
改成
<img src="showimg.php?<?php echo $ra[main_pic_src];?>" alt="..." />

我剛剛實測過是可行的 從本地端讀取遠端伺服圖的同一張圖片檔 內容變更檔名不變 本地端的圖片不會被cache

demo code: index.php

<!DOCTYPE html>
<html lang="zh-tw">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>TEST</title>
</head>
<body>
<h3>測試載入同名圖片是否會cache</h3>
<img src="showimg.php?http://www.web3d.url.tw/ITHELP/tmp/test1.jpg" />
<hr/>
<img src="showimg.php?http://friendoprod.blob.core.windows.net/missionpics/images/4681/member/ba29d216-5ccb-4a01-bc4f-bc4ac626bbe4.jpg" />
<img src="showimg.php?http://image.dbbqb.com/dxdl" />
</body>
</html>
看更多先前的回應...收起先前的回應...
st474ddr iT邦新手 5 級 ‧ 2019-12-27 16:53:25 檢舉

大大感謝您細心的回覆
我試了這個方法
只是目前圖片全部都無法顯示了QQ
我可能還要找找看問題出在哪
它的request URL
https://ithelp.ithome.com.tw/upload/images/20191227/20123565CPD3pkmClG.jpg
我連過去 也看不到圖片
應該是這裡出了問題

ccutmis iT邦高手 8 級 ‧ 2019-12-27 16:58:06 檢舉
st474ddr iT邦新手 5 級 ‧ 2019-12-27 17:01:32 檢舉

allow_url_fopen都是on
我有看到問題回報了
SSL fatal protocol error
我現在來找一下處理辦法
好像跟https有關

ccutmis iT邦高手 8 級 ‧ 2019-12-27 17:26:36 檢舉
<img src="showimg.php?https://images-na.ssl-images-amazon.com/images/I/61eY5-dS%2BkL._AC_SL1000_.jpg" />

跟https無關,我試上面的https開頭的圖片一樣能work...
目前你可以朝兩個方面試
1.把
echo file_get_contents($_SERVER['QUERY_STRING'].'?t='.time());
改成
echo file_get_contents("圖片完整路徑");

這邊用意是測試你的php檔裡面的img崁入showimg.php是不是能正常顯示圖片,如果不行,那就是把它調到可以正常顯示,如果可以正常顯示,那就是傳到showimg.php的路徑問題或是遠端主機擋了file_get_contents()

2.要測試showimg.php帶入的圖片路徑能不能正常顯示很簡單,直接在網址列打 http://localhost/myproject/showimg.php?接完整路徑

https://ithelp.ithome.com.tw/upload/images/20191227/20028574TpESLcZZXJ.png

st474ddr iT邦新手 5 級 ‧ 2019-12-27 17:33:12 檢舉

大大

目前你可以朝兩個方面試

這兩個方法都看不到圖片
原因就是那個
SSL fatal protocol error

不過我去PHP的文件中
我有查到解決辦法
我只要在file_get_contents前面加個@就可以了
變成這樣

echo @file_get_contents($_SERVER['QUERY_STRING'].'?t='.time());

也解決我的問題

不過雖然解決問題了 容小弟多問一下
大大您這方法為何可以擋住proxy的快取

ccutmis iT邦高手 8 級 ‧ 2019-12-27 17:43:59 檢舉

恭喜 能解決問題就好~
為何可以... 我只能說是經驗... (真正的原因是快下班了XD)

超人邦友F大 說的解法好像跟這個有關 你有空也可以研究一下
https://www.inmotionhosting.com/support/website/disable-caching-htaccess/

目前這個方法每次載入圖片就會去call showimg.php,這個就是我說的會增加伺服器負擔(要慎用,有些圖片不在意那個cache一兩小時時間的,就別用),可能要再觀察看看或是改用 超人邦友F大建議的方法。

st474ddr iT邦新手 5 級 ‧ 2019-12-27 17:48:39 檢舉

好的感謝大大 我研究研究
真的有感頁面載入速度有增加一些些

firecold iT邦新手 3 級 ‧ 2019-12-27 17:52:35 檢舉

雖然已經有最佳解答了
但其實圖片還是命名重新編碼為好
在改資料庫關係就好

不管是cache還是要配合CDN
都比較好處理

當然有些特殊情境可能需要這要處理
EX第三方合作 舊資料處理之類的

ccutmis iT邦高手 8 級 ‧ 2019-12-27 19:48:36 檢舉

樓上說的是對的。

st474ddr iT邦新手 5 級 ‧ 2019-12-30 09:55:28 檢舉

但其實圖片還是命名重新編碼為好
在改資料庫關係就好

大大其實我不太懂這是什麼意思
是代表我目前的圖片名稱取的不好嗎?

ccutmis iT邦高手 8 級 ‧ 2019-12-30 10:16:50 檢舉

目前樓主的作法是 每次上傳成功後不變更檔名 上傳的新圖會覆蓋舊圖 因此產生了快取到舊檔的問題

如果改成是上傳後會另外存成新圖檔 檔名不要跟舊圖重覆 這樣就不會有快取的問題了
(例如原圖是 image-20191220-153032-erqwrfas.jpg 新上傳的圖是 image-20191230-100942-hrtwaqer.jpg 確定新圖檔沒問題就把舊圖刪除 資料庫記錄舊圖的路徑要改成新圖路徑) 檔名路徑不同就不需要處理快取了 這是我的淺見

實務上怎麼處理樓主自行評估就好 很多事情沒有標準答案 先解決問題再來思考優化解決方案

st474ddr iT邦新手 5 級 ‧ 2019-12-30 15:40:39 檢舉

喔喔 我了解意思了
因為圖片會上傳非常多個
而且使用可能會一直改圖
我擔心這會讓圖片資料夾存了太多 浪費空間
所以命名才這樣設定

我都會刪掉舊的+新的另存檔名(參數串)
如果你要更保險,或許可以將舊的另存到另一個資料夾,再定時刪除?

jhit03 iT邦新手 5 級 ‧ 2020-01-04 12:46:19 檢舉

billingchan iT邦新手 5 級 ‧ 2020-01-03 12:17:54
我都會刪掉舊的+新的另存檔名(參數串)
如果你要更保險,或許可以將舊的另存到另一個資料夾,再定時刪除?

↑我就是同時用這兩種方法

0
airthomas
iT邦見習生 ‧ 2020-01-05 16:57:00

如果是在php的話,可在php.ini 找一下 opcache.revalidate_freq,把值改為 0 便可

我要發表回答

立即登入回答