有這個一個需求:顯示在系統中的圖片需要隱藏其真實的檔名和路徑,其真實檔名不能被下載儲存下來。其它資訊:圖片儲存在專用的圖片伺服器上。
試用了幾種方法,記錄下。
<body oncontextmenu="javascript:return false">
<img src="./images/1.jpg" style="pointer-events: none; height: 100px"/>
</body>
上面img標籤上的pointer-events: none,可以禁用全部滑鼠事件包括右鍵選單
body標籤上的 oncontextmenu="javascript:return false" 禁用整個頁面的右鍵選單
然而還可以透過ctrl+s儲存網頁下載整個頁面上的圖片
object標籤
<object type="image/jpg" data="./images/b.jpg" height="100" style="pointer-events: none;"></object>
效果同img標籤
embed標籤
<embed type="image/jpg" src="./images/2.jpg" height="100" style="pointer-events: none;"></embed>
Edge和Chrome瀏覽器 儲存下的網頁中竟然沒有embed標籤引用的圖片,目前還是很好的,可惜用firefox還是可以正常下載
base64編碼
<body oncontextmenu="javascript:return false">
<img src="./images/1.jpg" style="pointer-events: none; height: 100px" onload="getData(this)" />
<script>
function getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, img.width, img.height);
var dataURL = canvas.toDataURL("image/png");
return dataURL;
}
function getData(this_obj) {
var data = getBase64Image(this_obj);
this_obj.src = data;
}
</script>
</body>
如此這種將src屬性由url替換為base64編碼的形式 會導致src內容確實被替換了,但頁面似乎一直沒辦法載入完成。
換個寫法:
<body></body>
<script>
function getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, img.width, img.height);
var dataURL = canvas.toDataURL("image/png");
return dataURL;
}
function getData(this_obj) {
const img_obj = new Image();
img_obj.src = "./images/1.jpg";
img_obj.onload = function (e) {
const data = getBase64Image(img_obj);
const img = document.createElement("img");
img.style.height = 100 + "px";
img.src = data;
document.body.appendChild(img);
};
}
getData();
</script>
如此才算正常
後端返回圖片內容
<img src="../test/request_img.php" style="height: 100px"/>
後端程式碼
<?php
// 圖片檔案的路徑
$imagePath = '../html-demos/images/square.jpg';
$name = 'aa.jpg';
// 確保圖片檔案存在
if (file_exists($imagePath)) {
// 設定正確的內容型別(MIME型別)
header('Content-Description: File Transfer');
header('Content-Type: image/jpeg');
header('Content-Disposition: attachment; filename="' . $name . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($imagePath));
// 讀取圖片內容並直接輸出
readfile($imagePath);
exit;
} else {
// 圖片不存在的錯誤處理
header('HTTP/1.0 404 Not Found');
}
如此這樣,確實達到了隱藏圖片名和路徑的效果。只是圖片在本地時尚且可以,圖片在遠端的話似乎效率不高。
不管怎麼說,使用後端返回的方法畢竟要經過後端轉接,耗費伺服器資源,還是採用前一種吧。