Большинство веб-программистов рано или поздно сталкивается с вопросом защиты изображений от копирования для последующего распространения. Обычно, это решается при помощи GD — лепкой на нужные картинки большой прозрачной надписи типа «www.%sitename%.ru» или сильным уменьшением качества изображения, реже — блокировкой контекстного меню, ещё реже — клавиши Ctrl.
В своё время, когда у меня встал подобный вопрос, но варианты «водяные знаки» или «ухудшение качества» были неприемлемы, я заморочился и придумал кое-какое решение. Это, конечно, не панацея (кому надо — тот всё равно утянет), но в качестве «защиты от дурака» справляется на ура.
Кому интересно, добро пожаловать под кат.
Чтобы не быть голословным, сразу приведу пример, который потом буду подробно разбирать: пример
Сразу оговорюсь: к сожалению, не спасает, если в Safari сохранить страницу, как web-архив.
JS
Блокируем контекстное меню и клавишу Ctrl:
*для удобства, я почти всегда использую jQuery.
HTML
Говорим браузеру, что кэшировать ничего не нужно, а актуальность контента закончилась в прошлом веке:
Картинку, которую хотим защитить, мы выводим, как бэкграунд div'а, внутри которого вставляем тэг img с прозрачной картинкой 1х1 пиксель:
PHP
Думаю, что вы заметили параметр «showImg=84f5452a1fb1625ba0e251646049a60a», который передается в наш индекс файл. Обратимся к php-коду, чтобы понять, как он формируется и для чего он нужен:
Содержимое скрипта «hana_kartinke.php»:
Пользователь видит картинку, но не может её сохранить ни при помощи контекстного меню (оно заблокировано), ни копипастом (блок на Ctrl), ни как Файл\Сохранить страницу, а при попытке посмотреть картинку перейдя по ссылке из исходников html, он увидит многозначительную надпись «Epic fail! =)».
В принципе, можно этот метод использовать и в совокупности с GD (водяные знаки и урезание качества). Но это уже параноя, на мой взгляд.
Надеюсь, что кому-то эта информация будет полезна.
UPD
Повторюсь — это не панацея, это — защита от дурака.
UPD 2
Для критиков и минусующих, хочу пояснить суть: я долгое время проработал в маркетинге и занимался программированием онлайн-опросов, а в мире маркетинга существует одна авторитетная организация — ESOMAR, в требования которой (касательно онлайн-опросов) входит пункт по защите контента (картинки, видео и т.п.) от сохранения пользователями, при этом, визуально этого заметно быть не должно (т.е. никаких водяных знаков и урезаний качества).
Понятно, что защитить что-либо в интернете невозможно (особенно, если оно УЖЕ попало к конечному пользователю — тот же кэш), но данные требования никто не отменял и пришлось как-то выкручиваться. В статье как раз и описан вариант решения подобной ситуации.
В своё время, когда у меня встал подобный вопрос, но варианты «водяные знаки» или «ухудшение качества» были неприемлемы, я заморочился и придумал кое-какое решение. Это, конечно, не панацея (кому надо — тот всё равно утянет), но в качестве «защиты от дурака» справляется на ура.
Кому интересно, добро пожаловать под кат.
Чтобы не быть голословным, сразу приведу пример, который потом буду подробно разбирать: пример
Сразу оговорюсь: к сожалению, не спасает, если в Safari сохранить страницу, как web-архив.
Разбор полётов
JS
Блокируем контекстное меню и клавишу Ctrl:
document.oncontextmenu = new Function("return false"); // блокируем контекстное меню
$(window).keypress(function(event){blockKey(event);}); // вызов функции блокировки клавиш
$(document).keypress(function(event){blockKey(event);}); // вызов функции блокировки клавиш
function blockKey(event){
keyCode = event.keyCode;
if (keyCode == '155'){ // не работает, т.к. PrintScreen является функцией заложенной в ОС, а не в браузер - до неё мы достучаться не сможем
alert('printscreen');
}
if (keyCode == '17'){ // блокировка Ctrl
alert('Блокировка включена.');
}
}
*для удобства, я почти всегда использую jQuery.
HTML
Говорим браузеру, что кэшировать ничего не нужно, а актуальность контента закончилась в прошлом веке:
<meta http-equiv="Expires" content="Fri, Jan 01 1997 05:00:00 GMT">
<meta http-equiv="Pragma" content="no-cache">
Картинку, которую хотим защитить, мы выводим, как бэкграунд div'а, внутри которого вставляем тэг img с прозрачной картинкой 1х1 пиксель:
<div style="width: 1000px; height: 70px; background:url(index.php?showImg=84f5452a1fb1625ba0e251646049a60a) no-repeat;">
<img src="fail.gif" alt="" style="width: 1000px; height: 70px;" oncontextmenu="return false;">
</div>
PHP
Думаю, что вы заметили параметр «showImg=84f5452a1fb1625ba0e251646049a60a», который передается в наш индекс файл. Обратимся к php-коду, чтобы понять, как он формируется и для чего он нужен:
<?php
session_start();
if (!$_GET['showImg']){ // выполняем при загрузке страницы
$_SESSION['imageId'] = md5(date('y-m-d H:i:s').rand()); // случайный хэш который присваиваем сессии
Header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); //Дата в прошлом
Header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
Header("Pragma: no-cache"); // HTTP/1.1
Header("Last-Modified: ".gmdate("D, d M Y H:i:s")."GMT"); // до кучи
?>
// ... наш html-код
<?php
}
if ($_GET['showImg']){ // выполняем в ответ на запрос браузера "хочу картинку для бэкграунда"
include_once('./hana_kartinke.php');
echo hana($_GET['showImg']);
}
?>
Содержимое скрипта «hana_kartinke.php»:
<?php
session_start();
function hana($code){
if ($code == $_SESSION['imageId']){ // если запрос соответствует случайной сессии
session_destroy(); // убиваем сессию
$_SESSION['imageId'] = 'fail'; // и присваиваем ей левое значение
$assa = file_get_contents('./habr.jpg'); // пихаем в переменную всё содержимое картинки, которую хотим защитить
}else{
$assa = 'Epic fail! =)'; // если запрос не соответствует сессии, пишем юзеру сообщение
}
return $assa; // возвращаем полученные данные в браузер юзера
}
?>
Результат
Пользователь видит картинку, но не может её сохранить ни при помощи контекстного меню (оно заблокировано), ни копипастом (блок на Ctrl), ни как Файл\Сохранить страницу, а при попытке посмотреть картинку перейдя по ссылке из исходников html, он увидит многозначительную надпись «Epic fail! =)».
В принципе, можно этот метод использовать и в совокупности с GD (водяные знаки и урезание качества). Но это уже параноя, на мой взгляд.
Надеюсь, что кому-то эта информация будет полезна.
UPD
Повторюсь — это не панацея, это — защита от дурака.
UPD 2
Для критиков и минусующих, хочу пояснить суть: я долгое время проработал в маркетинге и занимался программированием онлайн-опросов, а в мире маркетинга существует одна авторитетная организация — ESOMAR, в требования которой (касательно онлайн-опросов) входит пункт по защите контента (картинки, видео и т.п.) от сохранения пользователями, при этом, визуально этого заметно быть не должно (т.е. никаких водяных знаков и урезаний качества).
Понятно, что защитить что-либо в интернете невозможно (особенно, если оно УЖЕ попало к конечному пользователю — тот же кэш), но данные требования никто не отменял и пришлось как-то выкручиваться. В статье как раз и описан вариант решения подобной ситуации.