圖片隱藏真實的檔名及路徑的方法探討

carol2014發表於2024-06-27

有這個一個需求:顯示在系統中的圖片需要隱藏其真實的檔名和路徑,其真實檔名不能被下載儲存下來。其它資訊:圖片儲存在專用的圖片伺服器上。

試用了幾種方法,記錄下。

<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');
}

如此這樣,確實達到了隱藏圖片名和路徑的效果。只是圖片在本地時尚且可以,圖片在遠端的話似乎效率不高。

不管怎麼說,使用後端返回的方法畢竟要經過後端轉接,耗費伺服器資源,還是採用前一種吧。

相關文章