Perfection or Vanity

Project: Terminated

Blog nie jest już dalej prowadzony ani aktualizowany. Mimo tego, wpisy i komentarze są dalej dostępne. Możesz przeczytać pożegnalny wpis albo przejść do archiwum.

Nie kradnij mojego obrazka!

29 czerwca 2005

Ostatnio Vendro założył sobie fotoblog. Wszedłem z ciekawości. Cóż, layout jak layout, ale zdenerwował mnie dziecinny skrypt "blokujący" prawy klawisz myszy. Nie to, żebym od razu chciał ukraść jego obrazy. Po prostu mam w zwyczaju używać kliknięcia myszrolką, aby uaktywnić tryb przewijania samymi jej ruchami, góra-dół.

Kolega, po moim zwróceniu uwagi, skrypt zdjął. Lecz co z przyczyną, która spowodowała umieszczenie takiego "zabezpieczenia"? Obiecałem, że na coś wpadnę. No i wpadłem. Rozwiązanie proste i niedenerwujące. To znaczy troszkę denerwujące nadal może być - ponieważ sprawiamy, że klik prawym na zdjęciu nie jest naprawdę klikiem na nim samym. ;) No, ale zobaczycie o co chodzi dalej.

Każdy koder domyśli się prosto, że można oszukać użytkownika, nie umieszczając obrazka za pomocą tagu <img/>. Wykorzystamy do tego zwykły <div/>. Aby spełniał funkcje obrazka, należy nadać mu tło. Tło wypozycjonowane do górnej lewej krawędzi i bez powtarzania.

  1. <div style="background: url(photo.jpg) left top no-repeat;"></div>

No dobrze, powiecie. Ale przecież żadna przeglądarka nie wyświetli pustego <div/>. Zgadza się. Należy więc przepisać kod, dodając do środka pojemnika jakiś element. Ja wybrałem element <a/>. Dlaczego - o tym za chwilę.

  1. <div style="background: url(photo.jpg) left top no-repeat;"><a>&nbsp;</a></div>

Tak, popełniłem grzech. Umieściłem encję twardej spacji nie w tekście. Wymusiłem w ten sposób pokazanie się div'a. Pomińmy to proszę. Można użyć też przezroczystego obrazka 1px na 1px, ale to też grzech, a do tego jeszcze gorzej się to kojarzy. Więc pomińmy już ten cholerny enbeespe i zajmijmy się dalszymi problemami.

Otóż teraz pojemnik jest malutki. Widać tylko jego część - część zdjęcia - zawartą pod znakiem twardej spacji. Więc należy zmienić zachowanie elementu <a/>

  1. <div style="background: url(photo.jpg) left top no-repeat;"><a style="display: block; width: 151px; height: 137px;">&nbsp;</a></div>

Teraz obrazek wreszcie jest obrazkiem. Klikamy prawym. No i nie działa. Nie ma opcji zapisania obrazka, ale możemy wybrać opcję pokazania tła pojemnika. Czas się z tym uporać. :]

  1. <div style="background: url(photo.jpg) left top no-repeat;"><a href="#" style="display: block; width: 151px; height: 137px;">&nbsp;</a></div>

No i jest okej. No dobrze... prawie okej. Teraz klikając prawym na "obrazek" odwołujemy się do linka a nie do pojemnika. Lecz co z kursorem? Lecz co z linkiem, który mimo wszystko tam jest? Oto ostateczny kod, naprawiający wszystko. To znaczy obchodzący pewne niedogodności.

  1. <div style="background: url(photo.jpg) left top no-repeat;"><a href="#" onclick="return false;" style="cursor: default; display: block; width: 151px; height: 137px;">&nbsp;</a></div>

Zdarzenie onclick likwiduje dodanie znaczka "#" do paska adresu dokumentu i jego skrolowania do góry. Styl cursor: default likwiduje kursor łapki nad linkiem. Parszywy workaround, ale działa. Sprawdźcie sami:

Zanim odezwą się (słuszne) głosy o likwidowanie linka JavaScriptem, zmianę kursora i ogólnie głupotę bijącą z tego pomysłu, coś powiem. No bo jak można ukrywać obrazek, skoro po coś go tam umieszczamy? Otóż powodów może być parę. Ten sposób nie obroni nas przed przejęciem obrazka - to oczywiste mam nadzieję. Ale umieszczając zdjęcie w necie, uchronimy się przed pokemonami chcącymi sobie porysować po nim. Tymi mniej sprytniejszymi. Albo przed leniami - którzy nie ruszą PrntScrn albo podglądu źródła. Tak czy inaczej efekt czasem bywa szokujący, zwłaszcza dla początkującego - i można go wykorzystać raz czy dwa. Zresztą... ja tu tylko sprzątam. :-)

Jeśli już wiesz o co chodzi, to możesz rozważyć lżejszy (thx dla nbw za zwrócenie uwagi) i również poprawny kod:

  1. <a href="#" onclick="return false;" style="cursor: default; display: block; width: 151px; height: 137px; background: url(photo.jpg) left top no-repeat;">&nbsp;</a>

Informacje i hiperłącza

Blog o projektowaniu zgodnych ze standardami stron internetowych.

Praktyczne przykłady, sztuczki CSS, sposoby obchodzenia błędów przeglądarek, lekki i nieinwazyjny JavaScript, użyteczny design, dostępność i skrypty użytkownika.

RSS

Informacje o wpisie

Napisał riddle 29 czerwca 2005 o 22:35

Kategorie: CSS, HTML & Semantyka, Webdesign na luzie

Dodaj do:

Wpisy archiwalne

Archiwum miesięczne

Dzięki!

Dodaj bloga do Technorati Favorites Dodaj bloga do Del.icio.us Blog należy do sieci 10przykazań.com

  1. I wreszcie przestały by mnie denerwować głupie strony, na których nie mogę używać gestów, któe mam ustawione właśnie pod PPM.

  2. Hm.. no to nakombinowałeś :)

    Nie prościej byłoby zrobić po prostu linka z bg? :)

    [cały dzień klikam strony, więc wolniej myślę.. może czegoś nie załapałem]

  3. Ja tak mam u mnie z levelami. ale nie AŻ tak. Niech se pokemony biorą te obrazki :P Mimo to pomysł, i zastosowanie na pewno mi się kiedyś przyda.. a już na pewno tym z digartu :P

  4. nbw: Wiesz, najprawdopodobniej masz rację :) Ale racja, też jestem zamulony %P Tak czy inaczej div tam może zostać.. prościej chociażby tłumaczyć to w arcie. :-)

  5. A ja klikam prawym, wybieram "Pokaż informacje o stronie", zakładkę "Media", a tam mam kolejno wypisane wszystkie obrazki w dokumencie. Bez zamykania okna kopiuję sobie wszystkie nawet wygodniej niż klikając na każdym PPM. :D

  6. patrys: Nie no... hm.... kurczę... dobre.....zgadnijmy skąd to wiesz... kurczę, to ... hej! Wiem! :-) Nie jesteś pokemonem! :D

  7. O w mordę i właśnie zdradziłem im tajną technikę... :(

  8. hehe dzieki riddle ! tez kiedys myslalem o czyms podobnym :) tylko ze nie o divach tylko o tabelach ale prawie na jedno wychodzi :)

  9. Co by nie robić i tak da się do tego dostać. ;) Choćbym miał nawet analizować przebieg napięć w kablu. :P

    Ale swoją drogą dobrze, żeby to dię jakoś rozpowszechniło, bo też mam dosyć p-klik-blokerów. Choć generalnie to mi w sumie zwisa - jedna ze skryptozakładek załatwia wszystkie tego typu wku[rz/wi]ajki. ;)

  10. To tylko mój firefox posiada opcję "Pokaż obrazek tła"? ;-)

  11. "Pokaż obrazek tła" nie działa dla linków.

  12. Deer Park Alpha?

  13. A, jeszcze jedno ;)
    Ta wersja z DIVem ma swoje dobre strony - dla elementu a można nadać przez CSS background z alfa-png i znaczkiem © lub innym tekstem ;)

  14. Takie rzeczy w locie robi ImageMagick.

  15. Yano: Do tego, *wydaje mi się*, że wersja z div jest bardziej semantyczna. Mamy blok - zdjęcie, a blokowanie zapisywania jest w nim samym, w bloku. A nie blokuje sam blok. :D

  16. Owszem, ale jak ktoś jest lama to nie będzie wiedzieć jak zrobić watermark na obrazku ;)… eee… w sumie tez nie będzie wiedział co to kanał alfa w png, więc na jedno wychodzi…
    No dobra, późno już ;P

  17. Dodam jeszcze, że umieszczenie href="#jakistarget", na stronie gdzie nie istnieje żaden element z id="jakistarget", zapobiega skrollowaniu do góry, więc onclick odpada. No i lepszym wyjściem niż &nbsp; jest jakiś tekst + text-indent: -999em;

  18. A ma ktoś może jakiś skrypt lub coś, co by blokowało Plik/Zapisz Jako, w końcu nie którzy tak kopiują strony, a o programie do robienia luster nie mają zielonego pojęcia.

  19. Chyba żart. :) Nie da się.

  20. No dla nie znających sie w temacie super :)
    Ale mi sciagniecie obrazka zajelo, 3sek ;-)
    Ale podoba mi sie ten chwyt, super :)

    Pozdrawiam.

  21. Taa, a w FF jest coś takiego jak:
    Narzędzia > Informacje o stronie > Media
    i button Zapisz jako.

    Ostatecznie nawet każdy lamer potrafi zrobić PrtSc i wie gdzie w Windows znajduje się Paint. No ale nie ma to jak zasmiecić kod niesemantycznym badziewiem.

    Artykuł fajny ale jako ciekawostka, do wykorzystania w praktyce nie do przyjęcia, jak dla mnie.

  22. Proponuję krótszy kod bez linków. Potrzebny będzie plik o nazwie zaslona.gif zawierający w 100% przezroczystość (plik mało zajmuje – 48 bajtów).

    Oto kod:

    <img alt=„opis” src=„zaslona.gif” style=„background:url(mojobrazek) left top no-repeat;width:310px;height:150px;”>

    Kliknięcie na pokaż obrazek powoduje ukazanie się pustej białej strony. hehe.

    Nie twierdzę oczywiście, że jest to profesjonalne rozwiązanie, ponieważ profesjonalna strona nie blokuje ściągania obrazków – powoduje to tylko rozrost kodu HTML lub użycie dodatkowych grafik (czy tak, czy inaczej zwiększa transfer).

  23. Strasznie zagmatwane te sposoby. Przychylam sie do pomyslu hidee z pewnymi modyfikacjami.

    Zamiast plik nazwac zaslona.gif – nalezy nazwac tak jak brzmialby wlasciwy plik np. pies.gif, a style przeniesc do zewnetrznego arkusza. Oczywiscie wlasciwemu obrazkowi najlepiej nadac nazwe, ktora nie bedzie sie z nim zupelnie kojarzyc.

    Dodajac klasy do img jestesmy w stanie latwo zarzadzac duza liczba obrazow.

    Arkusz stylu nalezy zapisac w postaci sciezki bezwzglednej, a linki w nim zawarte w postaci wzglednej co rowniez utrudnia, jak zauwazylem, orientacje w poczatkowym webmasterom,a przynajmniej zdecydowanie wydluza wyszukiwanie wlasciwego pliku.

    Wady rozwiazania:

    1. jest to pornografia dla maniakow czystosci kodu (i zacieklych wrogow jednopikselowych gifow rowniez)
    2. nie nabierze sie na to osoba znajaca html i css (ale ta wada wystepuje w kazdym z powyzszych rozwiazan)
    3. w razie wylaczenia css’a w przegladarce nie zobaczymy obrazka (uwaga jw.)

    Zalety rozwiazania:

    1. dosc prosty kod – latwy do zastosowania
    2. osoba przegladajaca widzi akcje zapisywania obrazka i mysli ze go ukradla (kto po zapisaniu od razu wyswietla obrazek z dysku?!?) – rozczarowanie przychodzi potem ;-)
    3. nie do przejscia jezeli ktos nie zna html’a i css’a
    4. nawet jezeli ktos zna html i css to mu sie moze znudzic szukanie obrazkow, jezeli arkusz ze stylami bedzie przydlugawy;
    5. zgodny z xhtml i css (przechodzi walidacje)
  24. bardzo miłe rozwiązanie, ja spotkałem się z innym zastosowanym na stronie Dave’a Chapella ;)

    Obraz jako tło tabeli, pusty gif 100% 100% jako tło celi.
    Proste i musze przyznać że pobrałem z 50 zdjęć... tak myślałem bo rzeczywiscie zapisywalem sobie x.gif 1×1piksela ;) więcej już mi się nie chciało.

  25. Dla osób, które chcą zablokować obrazek również dla HTML-owców podaję uzupełnienie rozwiązania nr 22:
    Wystarczy w PHP napisać krótki skrypt wysyłający obrazek

    <?php

    $adr=explode(’/’,$_SERVER[‘REFERER’]) if(isset($adr2)&&(strtolower($adr2)==„Twoja domena malymi literami, np.: hidee.org”)) $plik=„obrazek”;else $plik=„obrazek z figą”; $fp=fopen($plik,„r”); $x=filesize($plik); $bytes=fread($fp,$x); fclose($fp); header(‘Content-type: image/jpeg’); print($bytes); //zczytywania pliku nie zastępuj includowaniem ponieważ //w obrazku mogą znajdować się bajty <?php i wystąpi błąd // trudny do wykrycia

    ?>

    wpis image/jpeg należy zamienić na image/gif dla obrazków w formacie gif.

    Skrypt ten podajemy w css, jako background-image: skrypt.php.
    Gdy przeglądarka zażąda obrazka to go otrzyma, zaś gdy użytkownik wpisze adres obrazka w linię adresu przeglądarki zobaczy … figę.

    Istnieje też inne rozwiązanie polegające na skonfigurowaniu HOT-LINKowania serwera:

    Dla typów JPG, GIF itd. włączamy ochronę przed HOT-LINKowaniem i zaznaczamy, aby nie dało się żądać obrazków bezpośrednio (prawie każdy serwer ma możliwość włączenia tego narzędzia).

    Polecam jednak skrypt php, ponieważ 99.99% serwerów obsługuje technologię PHP.

  26. Niestety wszystko dalej pozostaje w gestii przeglądarki. W epiphany obrazek tła w menu kontekstowym jest dostępny dla każdego elementu.
    Poza tym dblclick powoduje nizbyt ładny efekt zaznaczenia tego nbsp, ale to chyba da się jakoś załatwić przez text-indent.

    A co do blokowania po refererze to chyba użycie mod_rewrite lub odpowiednika jest szybsze i wydajniejsze niż PHP. Czy to właśnie miałeś na myśli pisząc „ochrona przed HOT-LINKowaniem”.

  27. Przeglądałem właśnie stare wpisy. Epiphany, przynajmniej 2.18, ma kopiuj adres obrazka… który nie nabiera się na sztuczkę.

    Pozdrawiam

  28. Hidee: skrypt się rozkłada w momencie jak wyślesz referera. Wiem, że tego nie da się z reguły zrobić bezpośrednio z przeglądarki, ale tak, czy inaczej można to łatwo obejść

  29. Ogólnie blokowanie obrazków, zdjęć jest dla mnie bezsensowne… jeśli już ktoś chce to niech sobie zrobi znak wodny na foto, żeby nikt nie użył dla własnych korzyści, albo niech w ogóle nie zamieszcza w sieci.
    Jeśli już ktoś koniecznie chce żeby niedoświadczeni użytkownicy nie mogli pobrać fotek, wystarczy zdjęcie umieścić w div jako tło, albo w img i na to na wyższą warstwę nałożyć pustego diva, nadać mu odpowiednie rozmiary i w ten sposób zakryć zdjęcie przeźroczystą tarczą ochronną przed ściąganiem.
    Niestety i tak te wszystkie sposoby są „G” warte, jeśli ktoś wie co oznaczają pliki tymczasowe przeglądarki (cache) i gdzie się znajdują ;)

  30. Poco szukać plików tymczasowych itd, klikasz prawym przyciskiem myszy gdziekolwiek na stronę wybierasz opcję „źródło strony” i tam szukasz swojego obrazka. Żaden div pusty czy niepusty nic na to nie pomoże. Do autora: obrazek to jpg o nazwie imgbgonlink-sample w katalogu images, prawda? Przydał by się skuteczny sposób na takich co sobie robią hosting plików z cudzych stron.

  31. Może tak być, jak mówicie.

  32. Kliknij prawym i na pokaż obrazek tła..
    Potem to już tylko zapisz jako..
    Ale gratuluje pomysłu ;)

  33. sposób z php jest najlepszy jako zabezpieczenie przed ściąganiem obrazków. Można umieścić obrazek bezpośrednio w img. Będzie to coś takiego:
    <img src=„obrazek.php” alt=„obrazek”/>
    a co do samych div‘ów to stosuje je na co dzień do wszelkich efektów graficznych. Jak ktoś chce zrobić mały kawałek obrazka animowany, to może zagnieździć diva w divie, nadrzędnemu ustawić animację na tło i resztę przysłonić maską w podrzędnym. Jedyny warunek to muszą być takiej samej wielkości (lub odpowiednio wypozycjonowane z pomocą css).
    Efektów jest wiele, ale gdy naprawę chcemy się zabezpieczyć przed wszystkim (i prtscr i, cache) trzeba zastosować PHP z GD. Blok taki jaki zrobił hidee i nakładanie znaku wodnego (gdzieś w rogu najlepiej). No i nic tego nie ruszy.

  34. czytelnik 34 28 maja 2009, 15:20

    hm… zawsze pozostaje spojrzeć w kod html lub css przeglądanej strony, wyciągnąć z niego url obrazke i wpisac adres w przeglądarkę... każdy obrazek można tak pobrać

Dodaj komentarz

Do formatowania komentarzy używaj Textile (HTML nie działa). Szczególnie jeśli wklejasz większe fragmenty kodu. W razie niepewności użyj podglądu komentarza.

Wypowiedzi obraźliwe, infantylne oraz nie na temat będą moderowane – pisząc postaraj się zwiększyć wartość dyskusji.

Komentarze nie służą do wysyłania wiadomości albo informowania o błędach, itd. Chcesz coś mi napisać – skontaktuj się.