ฉันสร้างภาพโดยใช้ PHP lib
บางครั้งเบราว์เซอร์ไม่โหลดไฟล์ที่สร้างขึ้นใหม่
ฉันจะปิดการใช้งานแคชเฉพาะสำหรับรูปภาพที่ฉันสร้างขึ้นแบบไดนามิกได้อย่างไร
หมายเหตุ: ฉันต้องใช้ชื่อเดียวกันสำหรับภาพที่สร้างขึ้นเมื่อเวลาผ่านไป
ฉันสร้างภาพโดยใช้ PHP lib
บางครั้งเบราว์เซอร์ไม่โหลดไฟล์ที่สร้างขึ้นใหม่
ฉันจะปิดการใช้งานแคชเฉพาะสำหรับรูปภาพที่ฉันสร้างขึ้นแบบไดนามิกได้อย่างไร
หมายเหตุ: ฉันต้องใช้ชื่อเดียวกันสำหรับภาพที่สร้างขึ้นเมื่อเวลาผ่านไป
คำตอบ:
วิธีแก้ปัญหาทั่วไปและเรียบง่ายสำหรับปัญหานี้ที่ให้ความรู้สึกเหมือนแฮ็ก แต่ค่อนข้างพกพาได้คือการเพิ่มสตริงข้อความค้นหาที่สร้างแบบสุ่มให้กับคำขอสำหรับรูปภาพไดนามิกแต่ละรายการ
ตัวอย่างเช่น -
<img src="image.png" />
ก็จะกลายเป็น
<img src="image.png?dummy=8484744" />
หรือ
<img src="image.png?dummy=371662" />
จากมุมมองของเว็บเซิร์ฟเวอร์จะมีการเข้าถึงไฟล์เดียวกัน แต่จากมุมมองของเบราว์เซอร์ไม่สามารถทำการแคชได้
การสร้างหมายเลขสุ่มสามารถเกิดขึ้นได้ทั้งบนเซิร์ฟเวอร์เมื่อให้บริการเพจ (ตรวจสอบให้แน่ใจว่าเพจนั้นไม่ได้ถูกแคช ... ) หรือบนไคลเอนต์ (โดยใช้ JavaScript)
คุณจะต้องตรวจสอบว่าเว็บเซิร์ฟเวอร์ของคุณสามารถรับมือกับเคล็ดลับนี้ได้หรือไม่
กลยุทธ์การแคชเบราว์เซอร์สามารถควบคุมได้โดยส่วนหัว HTTP โปรดจำไว้ว่าพวกเขาเป็นเพียงคำใบ้จริงๆ เนื่องจากเบราว์เซอร์ไม่สอดคล้องกันอย่างมากในฟิลด์นี้ (และอื่น ๆ ) คุณจะต้องมีส่วนหัวหลายตัวเพื่อให้ได้เอฟเฟกต์ที่ต้องการในเบราว์เซอร์ต่างๆ
header ("Pragma-directive: no-cache");
header ("Cache-directive: no-cache");
header ("Cache-control: no-cache");
header ("Pragma: no-cache");
header ("Expires: 0");
หากคุณต้องการทำแบบไดนามิกในเบราว์เซอร์โดยใช้จาวาสคริปต์นี่คือตัวอย่าง ...
<img id=graph alt=""
src="http://www.kitco.com/images/live/gold.gif"
/>
<script language="javascript" type="text/javascript">
var d = new Date();
document.getElementById("graph").src =
"http://www.kitco.com/images/live/gold.gif?ver=" +
d.getTime();
</script>
โซลูชันที่ 1 ไม่ดีมันใช้งานได้ แต่การเพิ่มสตริงการสืบค้นแบบสุ่มหรือการประทับเวลาที่แฮ็กกี้ไปที่ส่วนท้ายของไฟล์รูปภาพของคุณจะทำให้เบราว์เซอร์ดาวน์โหลดซ้ำและแคชรูปภาพทุกเวอร์ชันทุกครั้งที่โหลดหน้าเว็บโดยไม่คำนึงถึงสภาพอากาศที่รูปภาพจะเปลี่ยนไปหรือไม่ก็ตาม บนเซิร์ฟเวอร์
โซลูชันที่ 2 ไม่มีประโยชน์ การเพิ่มnocache
ส่วนหัวให้กับไฟล์รูปภาพไม่เพียง แต่ใช้งานได้ยากเท่านั้น แต่ยังทำไม่ได้อย่างสมบูรณ์เพราะคุณต้องคาดการณ์ว่าจะต้องใช้เวลาใดล่วงหน้าในครั้งแรกที่คุณโหลดรูปภาพใด ๆ ที่คุณคิดว่าอาจมีการเปลี่ยนแปลงในบางจุดในอนาคต .
วิธีที่ดีที่สุดแน่นอนฉันได้พบในการแก้ปัญหานี้คือการใช้etagsภายใน .htaccessไฟล์ในไดเรกทอรีภาพของคุณ ข้อความต่อไปนี้จะบอกให้ Apache ส่งแฮชเฉพาะไปยังเบราว์เซอร์ในส่วนหัวของไฟล์รูปภาพ แฮชนี้จะเปลี่ยนแปลงเมื่อมีการแก้ไขไฟล์รูปภาพเท่านั้นและการเปลี่ยนแปลงนี้จะทำให้เบราว์เซอร์โหลดภาพซ้ำในครั้งถัดไปที่มีการร้องขอ
<FilesMatch "\.(jpg|jpeg)$">
FileETag MTime Size
</FilesMatch>
ฉันตรวจสอบคำตอบทั้งหมดและคำตอบที่ดีที่สุดดูเหมือนจะเป็น (ซึ่งไม่ใช่):
<img src="image.png?cache=none">
ในตอนแรก.
อย่างไรก็ตามหากคุณเพิ่มcache = noneพารามิเตอร์ (ซึ่งเป็นคำว่า "ไม่มี" แบบคงที่) จะไม่มีผลอะไรเลยเบราว์เซอร์จะยังโหลดจากแคช
วิธีแก้ไขปัญหานี้คือ:
<img src="image.png?nocache=<?php echo time(); ?>">
โดยพื้นฐานแล้วคุณจะเพิ่มการประทับเวลาของยูนิกซ์เพื่อทำให้พารามิเตอร์เป็นแบบไดนามิกและไม่มีแคชมันใช้งานได้
อย่างไรก็ตามปัญหาของฉันแตกต่างกันเล็กน้อย: ฉันกำลังโหลดรูปภาพแผนภูมิ php ที่สร้างขึ้นในทันทีและควบคุมเพจด้วยพารามิเตอร์ $ _GET ฉันต้องการให้อ่านรูปภาพจากแคชเมื่อพารามิเตอร์ URL GET ยังคงเหมือนเดิมและไม่แคชเมื่อพารามิเตอร์ GET เปลี่ยนไป
ในการแก้ปัญหานี้ฉันต้องแฮช $ _GET แต่เนื่องจากเป็นอาร์เรย์นี่จึงเป็นวิธีแก้ปัญหา:
$chart_hash = md5(implode('-', $_GET));
echo "<img src='/images/mychart.png?hash=$chart_hash'>";
แก้ไข :
แม้ว่าโซลูชันข้างต้นจะทำงานได้ดี แต่บางครั้งคุณต้องการให้บริการเวอร์ชันแคชจนกว่าไฟล์จะมีการเปลี่ยนแปลง (ด้วยวิธีแก้ปัญหาข้างต้นจะปิดการใช้งานแคชสำหรับรูปภาพนั้นอย่างสมบูรณ์) ดังนั้นในการให้บริการรูปภาพที่แคชจากเบราว์เซอร์จนกว่าจะมีการเปลี่ยนแปลงในการใช้ไฟล์รูปภาพ:
echo "<img src='/images/mychart.png?hash=" . filemtime('mychart.png') . "'>";
filemtime () ได้รับเวลาแก้ไขไฟล์
ฉันรู้ว่าหัวข้อนี้เก่า แต่ได้รับการจัดอันดับที่ดีมากใน Google ฉันพบว่าการใส่สิ่งนี้ในส่วนหัวของคุณได้ผลดี
<meta Http-Equiv="Cache-Control" Content="no-cache">
<meta Http-Equiv="Pragma" Content="no-cache">
<meta Http-Equiv="Expires" Content="0">
<meta Http-Equiv="Pragma-directive: no-cache">
<meta Http-Equiv="Cache-directive: no-cache">
ฉันแค่มองหาวิธีแก้ปัญหานี้และคำตอบข้างต้นไม่ได้ผลในกรณีของฉัน (และฉันมีชื่อเสียงไม่เพียงพอที่จะแสดงความคิดเห็นเกี่ยวกับเรื่องนี้) ปรากฎว่าอย่างน้อยสำหรับกรณีการใช้งานของฉันและเบราว์เซอร์ที่ฉันใช้ (Chrome บน OSX) สิ่งเดียวที่ดูเหมือนจะป้องกันการแคชคือ:
Cache-Control = 'no-store'
เพื่อความสมบูรณ์ตอนนี้ฉันใช้ 'no-cache, no-store, must-revalidate' ทั้ง 3 ตัว
ดังนั้นในกรณีของฉัน (ให้บริการรูปภาพที่สร้างขึ้นแบบไดนามิกจาก Flask ใน Python) ฉันต้องทำสิ่งต่อไปนี้เพื่อหวังว่าจะทำงานในเบราว์เซอร์ให้ได้มากที่สุด ...
def make_uncached_response(inFile):
response = make_response(inFile)
response.headers['Pragma-Directive'] = 'no-cache'
response.headers['Cache-Directive'] = 'no-cache'
response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
response.headers['Pragma'] = 'no-cache'
response.headers['Expires'] = '0'
return response
การเปลี่ยนแหล่งที่มาของภาพคือทางออก คุณสามารถทำได้โดยเพิ่มการประทับเวลาหรือตัวเลขสุ่มลงในภาพ
จะเป็นการดีกว่าที่จะเพิ่มการตรวจสอบเช่นข้อมูลที่รูปภาพแสดง สิ่งนี้เปิดใช้งานการแคชเมื่อเป็นไปได้
ลองเพิ่มอีกวิธีหนึ่งลงในพวง
การเพิ่มสตริงที่ไม่ซ้ำกันในตอนท้ายเป็นวิธีที่สมบูรณ์แบบ
example.jpg?646413154
โซลูชันต่อไปนี้จะขยายวิธีการนี้และให้ทั้งความสามารถในการแคชและดึงข้อมูลเวอร์ชันใหม่เมื่ออัปเดตรูปภาพ
เมื่ออัปเดตภาพแล้วเวลาของไฟล์จะเปลี่ยนไป
<?php
$filename = "path/to/images/example.jpg";
$filemtime = filemtime($filename);
?>
ตอนนี้ส่งออกภาพ:
<img src="images/example.jpg?<?php echo $filemtime; ?>" >
ฉันมีปัญหานี้และเอาชนะแบบนี้
var newtags='<div class="addedimage"><h5>preview image</h5><img src="'+one+'?nocache='+Math.floor(Math.random() * 1000)+'"></div>';
ฉันใช้สิ่งนี้เพื่อแก้ปัญหาที่คล้ายกันของฉัน ... กำลังแสดงตัวนับรูปภาพ (จากผู้ให้บริการภายนอก) ไม่ได้รีเฟรชอย่างถูกต้องเสมอไป และหลังจากเพิ่มพารามิเตอร์แบบสุ่มทุกอย่างก็ใช้ได้ดี :)
ฉันได้ต่อท้ายสตริงวันที่เพื่อให้แน่ใจว่ามีการรีเฟรชอย่างน้อยทุกนาที
โค้ดตัวอย่าง (PHP):
$output .= "<img src=\"http://xy.somecounter.com/?id=1234567890&".date(ymdHi)."\" alt=\"somecounter.com\" style=\"border:none;\">";
ผลลัพธ์ในsrc
ลิงก์เช่น:
http://xy.somecounter.com/?id=1234567890&1207241014
หากคุณมี URL รูปภาพแบบฮาร์ดโค้ดตัวอย่างเช่นhttp://example.com/image.jpgคุณสามารถใช้ php เพื่อเพิ่มส่วนหัวให้กับรูปภาพของคุณ
ก่อนอื่นคุณต้องทำให้ apache ประมวลผล jpg ของคุณเป็น php ดูที่นี่: เป็นไปได้ไหมที่จะรัน PHP ด้วยนามสกุล file.php.jpg
โหลดรูปภาพ (imagecreatefromjpeg) จากไฟล์จากนั้นเพิ่มส่วนหัวจากคำตอบก่อนหน้า ใช้ส่วนหัวของฟังก์ชัน php เพื่อเพิ่มส่วนหัว
จากนั้นส่งออกภาพด้วยฟังก์ชั่น imagejpeg
โปรดสังเกตว่าการปล่อยให้ php ประมวลผลภาพ jpg นั้นไม่ปลอดภัยมาก นอกจากนี้โปรดทราบว่าฉันยังไม่ได้ทดสอบโซลูชันนี้ดังนั้นจึงขึ้นอยู่กับคุณที่จะทำให้มันใช้งานได้
ง่ายส่งตำแหน่งส่วนหัวเดียว
ไซต์ของฉันมีรูปภาพหนึ่งรูปและหลังจากอัปโหลดรูปภาพไม่มีการเปลี่ยนแปลงฉันจึงเพิ่มรหัสนี้:
<?php header("Location: pagelocalimage.php"); ?>
งานสำหรับฉัน