如何从浏览器的右键菜单中禁用“另存为…”以防止客户端下载视频?

是否有更完整的解决方案来阻止客户端直接访问文件路径?


当前回答

我通常使用的最好的方法很简单,我完全禁用整个页面的上下文菜单,纯html+javascript:

 <body oncontextmenu="return false;">

就是这样!我这么做是因为你总是可以通过右键点击看到源代码。 好吧,你说:“我可以直接使用浏览器查看源代码”,这是真的,但我们从事实开始,你不能停止下载html5视频。

其他回答

作为客户端开发人员,我推荐使用blob URL, blob URL是一个引用二进制对象的客户端URL

<video id="id" width="320" height="240"  type='video/mp4' controls  > </video>

在HTML中,让你的视频src为空, 在JS中使用AJAX获取视频文件,确保响应类型是blob

window.onload = function() {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'mov_bbb.mp4', true);
    xhr.responseType = 'blob'; //important
    xhr.onload = function(e) {
        if (this.status == 200) {
            console.log("loaded");
            var blob = this.response;
            var video = document.getElementById('id');
            video.oncanplaythrough = function() {
                console.log("Can play through video without stopping");
                URL.revokeObjectURL(this.src);
            };
            video.src = URL.createObjectURL(blob);
            video.load();
        }
    };
    xhr.send();
}

注意:大文件不建议使用此方法

EDIT

使用跨源阻塞和头标记检查来防止直接下载。 如果视频是通过API传递的;使用不同的http方法(PUT / POST)来代替'GET'

你在浏览器中看到的一切都是下载的内容。这里提到的问题是如何在浏览器中保存这些内容。要查看内容,客户端浏览器从内容服务器下载并在本地提供。

一种流行的解决方案是将(短暂的)内容仅保存在浏览器中,并在有限的时间内,以一种不能直接保存的方式保存。blob是这种方法的一种实现,它具有减少带宽和存储开销的额外好处,因为内容存储在二进制对象中。

内容的短有效期使得普通用户几乎不可能持久存储,因为在用户尝试保存过期内容之前会显示新内容。

简单的回答,

你不能

如果他们正在看你的视频,他们已经有了

你可以让他们慢下来,但不能阻止他们。

PHP将html5视频标记和一个会话一起发送,其中键是一个随机字符串,值是文件名。

ini_set('session.use_cookies',1);
session_start();
$ogv=uniqid(); 
$_SESSION[$ogv]='myVideo.ogv';
$webm=uniqid(); 
$_SESSION[$webm]='myVideo.webm';
echo '<video autoplay="autoplay">'
    .'<source src="video.php?video='.$ogv.' type="video/ogg">'
    .'<source src="video.php?video='.$webm.' type="video/webm">'
    .'</video>'; 

现在PHP被要求发送视频。PHP恢复文件名;删除会话并立即发送视频。此外,所有“无缓存”和mime类型的头必须存在。

ini_set('session.use_cookies',1);
session_start();
$file='myhiddenvideos/'.$_SESSION[$_GET['video']];
$_SESSION=array();
$params = session_get_cookie_params();
setcookie(session_name(),'', time()-42000,$params["path"],$params["domain"],
                                         $params["secure"], $params["httponly"]);
if(!file_exists($file) or $file==='' or !is_readable($file)){
  header('HTTP/1.1 404 File not found',true);
  exit;
  }
readfile($file);
exit:

现在,如果用户复制url在一个新的选项卡或使用上下文菜单,他将没有运气。

我发现了一个类似问题的好答案,使用PHP而不是JavaScript以获得更好的安全性。

我想使用浏览器的默认播放器在用户的浏览器中播放test.mp4(就像在Web页面上单击了URL/test.mp4一样),但需要密码,该密码由用户提供或由软件内部提供。

下面是这个想法的一个简要概述。它开始于用户去(运行)一个我写的叫做secure.php的程序来播放test.mp4。

文件test.mp4位于一个子目录("secureSubdirectory")中,该子目录包含一个包含"Require all denied"的.htaccess。这立即阻止了任何通过URL的直接访问。

当secure.php运行时,它提供一个密码(或向用户查询密码),然后对自己执行一个包含密码的POST,使用一个salt,使用PHP命令验证它:

$Hash=base64_encode(hash_hmac("sha256",$Pwd,$Salt,true));
$HashesAreSame=hash_equals($Hash,$GoalHash);

然后测试test.mp4是否存在,并执行以下PHP代码将test.mp4文件作为字节流返回给用户的浏览器:

header("Content-Type: video/mp4");
echo file_get_contents("secureSubdirectory/$path");
exit;

视频和预期的一样。如果我然后右键单击显示视频的页面并尝试保存视频,结果文件将只包含一个错误字符串,如“错误:密码未找到”,因为test.mp4是使用普通的secure.php URL查询的,而不是使用正确的密码通过POST。

当然,您可以使用浏览器调试工具的Network选项来获得响应有效负载(视频字节),但是如果浏览器提供了阻止访问调试工具的选项,那么PHP程序或.htaccess文件就可以阻止这种情况。

我无法想象失败的案例,但如果存在的话我会非常感兴趣,因为简单而完美的授权是非常罕见的事情。(请注意,由于这种方法依赖于密码,因此将其与用户关联并不是一种安全的身份验证方式,因为用户可能会意外或故意地发布或共享密码。)