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

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


当前回答

以下是我所做的:

function noRightClick() { alert("You cannot save this video for copyright reasons. Sorry about that."); } <body oncontextmenu="noRightClick();"> <video> <source src="http://calumchilds.com/videos/big_buck_bunny.mp4" type="video/mp4"> </video> </body> This also works for images, text and pretty much anything. However, you can still access the "Inspect" and the "View source" tool through keyboard shortcuts. (As the answer at the top says, you can't stop it entirely.) But you can try to put barriers up to stop them.

其他回答


你不能。

这是因为浏览器的设计目的就是:提供内容。但你可以让它更难下载。


方便的“解决方案”

我会把我的视频上传到第三方视频网站,比如YouTube或Vimeo。他们有很好的视频管理工具,优化设备的播放,他们努力防止他们的视频被撕掉,而你却没有付出任何努力。


解决方案1、禁用“右键单击”

你可以禁用上下文菜单事件,也就是“右键单击”。这将防止你的常规skiddie公然撕扯你的视频右击和另存为。但他们可以禁用JS,绕过这个问题,或者通过浏览器的调试器找到视频源。另外,这是糟糕的用户体验。在上下文菜单中有很多合法的东西,而不仅仅是另存为。


解决方案2,视频播放器库

使用自定义视频播放器库。它们中的大多数实现了视频播放器,可以根据您的喜好定制上下文菜单。你不会得到默认的浏览器上下文菜单。如果他们确实提供类似于另存为的菜单项,你可以禁用它。但同样,这是一个JS的解决方案。弱点类似于解决方案1。


解决方案3,HTTP直播

另一种方法是使用HTTP Live Streaming提供视频。它本质上是把视频切成块,然后一个接一个地播放。这就是大多数流媒体网站提供视频的方式。因此,即使你设法另存为,你只保存了一部分,而不是整个视频。收集所有的块并使用一些专用软件将它们缝合起来需要更多的努力。


解决方法4,在画布上作画

另一种技巧是在<canvas>上绘制<video>。在这种技术中,使用一些JavaScript,您在页面上看到的是一个<canvas>元素从隐藏的<video>渲染帧。因为它是一个<canvas>,上下文菜单将使用一个<img>的菜单,而不是一个<video>的。你会得到另存图像,而不是另存视频。


解决方案5,CSRF令牌

您还可以利用CSRF令牌。您可以让服务器在页面上发送一个令牌。然后使用该令牌获取视频。您的服务器在提供视频之前检查它是否是一个有效的令牌,或者获得HTTP 401。这个想法是,你只能通过有一个令牌来获得一个视频,你只能从页面来,而不是直接访问视频url。


作为客户端开发人员,我推荐使用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'

这是一个完整的解决方案禁用下载,包括右击>另存为…在上下文菜单中:

<video oncontextmenu="return false;" controlsList="nodownload">
</video>

@Clayton-Graul有我正在寻找的东西,除了我需要一个使用AngularJS的网站的CoffeeScript版本。以防你也需要它,下面是你在AngularJS控制器中输入的内容:

    # This is how to we do JQuery ready() dom stuff
    $ ->
        # let's hide those annoying download video options.
        # of course anyone who knows how can still download
        # the video, but hey... more power to 'em.
        $('#my-video').bind 'contextmenu', -> 
            false

“奇怪的事情正在k圈发生”(这是真的)

是的,你可以通过三个步骤做到这一点:


将要保护的文件放置在运行代码的目录的子目录中。 www.foo.com/player.html www.foo.com/videos/video.mp4 在该子目录中保存一个名为“”的文件。并添加下面的行。 www.foo.com/videos/.htaccess # .htaccess的内容 RewriteEngine上 RewriteCond % {HTTP_REFERER} ! ^ http://foo.com/。* $(数控) ^http://www.foo.com/.*$ [NC] 重写规则(mp4|mp3|avi)$ - [F]

现在源链接是无用的,但我们仍然需要确保任何试图下载该文件的用户不能直接获得该文件。

对于一个更完整的解决方案,现在为视频提供一个flash播放器(或html画布),不要直接链接到视频。只需删除右键菜单,添加到您的HTML: <body oncontextmenu="return false;">

结果:

www.foo.com/player.html可以正确播放视频,但如果你访问www.foo.com/videos/video.mp4:

错误代码403:禁止

这将工作直接下载,cURL,盗链,你的名字。

这是对两个问题的完整回答,而不是对“我能否阻止用户下载他们已经下载的视频”这个问题的回答。