图片隐藏真实的文件名及路径的方法探讨

有这个一个需求:显示在系统中的图片需要隐藏其真实的文件名和路径,其真实文件名不能被下载保存下来。其它信息:图片存储在专用的图片服务器上。

试用了几种方法,记录下。

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

如此这样,确实达到了隐藏图片名和路径的效果。只是图片在本地时尚且可以,图片在远程的话似乎效率不高。

不管怎么说,使用后端返回的方法毕竟要经过后端转接,耗费服务器资源,还是采用前一种吧。

posted @ 2024-06-27 10:58  carol2014  阅读(7)  评论(0编辑  收藏  举报