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ść

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ę.