UP - 04.22. 23:44 - a .htaccess tartama javítva, pár elírás javítva
Sziasztok,
Sokaktól láttam, hogy így meg úgy probléma, hogy a Google képkeresőjéből származó forgalom gyakorlatilag apró töredékére esett, amióta megújították a fejesek az egészet. Erre kínálnék most elég korrekt megoldást, amit a korábban, másik témában linkelt angol cikk alapján készítettem: Hotlinking protection and watermarking for Google Images
Hogy is működik?
Az alapelgondolás az, hogy az eredeti kép elérhető egy adott URL-en, így szolgáljuk ki a felhasználóknak is, de a keresőrobotoknak egy másik URL-t mutatunk (csapda URL) - a másik URL segítségével a mi oldalunkon (és csak a mi oldalunkon) az eredeti képet mutatjuk, mindenhol máshol pedig a watermarked képet. Tehát mi történik? Jön a Google robotja. A módosított URL-en kapja meg a képet, de az eredetit látja - beindexeli. Amikor pedig hotlinkeli, a módosított URL-en fogja kérni a képet, azt tűzi be magához, hisz azt hiszi, hogy az az eredeti képe lérési útvonala. Mi ezt érzékeljük, és mivel nem a mi oldalunkon van, ezért szimplán a watermarkos képet jelenítjük meg. Figyelem! A megoldás technikájából adódóan ez egy kissé black hat, hisz a keresőrobotnak mást mutatunk, mint a felhasználóknak. Mindenki saját felelősségre használja! Van egy nem black hat módszer, ezt az írásom közepe fele bemutatom (odaírva, hogy az a ne black hat), de az jóval kevésbé hatékony.
Feltételek:
- Egy mappában kell legyen minden kép, aminél szeretnéd megjeleníteni a watermarkot a G-ben.
- A .htaccess rewriteot el kell érd
Alapvetően két fajta megoldás van...
- gyorsabb: nem kell megvárni, míg a Google újraindexeli a képeket, cserébe azokat mind át kell majd mozgatni egy másik könyvtárba (= át kell nevezni a képek könyvtárát) => az összes képfeltöltő programon is változtatni kell
- lassabb: nem kell változtatni a filestruktúrán (ami egyébként apróság), de újra kell indexelni a G-nek a képeket
Megoldás - gyorsabb eset:
A legkisebb kiesést (1-2 másodperc) úgy érhetjük el, hogyha a jelenlegi képtároló mappához egyelőre nem nyúlunk hozzá. Helyette mellé létrehozunk egy másik mappát, gyakorlatilag mindegy, milyen névvel. Tegyük fel jelen esetben (hogy legyen egy konkrét példa), hogy jelenleg a képeink az images mappában vannak, és létrehoztunk mellé egy temp nevű mappát. Most a temp mappában hozzunk létre egy .htaccess filet, aminek a következő legyen a tartalma:
Kód:
RewriteEngine on
RewriteBase /eleres_a_temp_mappahoz/temp
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*)\.jpg image.php?i=$1&ext=jpg&type=jpeg
RewriteRule (.*)\.png image.php?i=$1&ext=png&type=png
A szemfülesek láthatják, hogy ez így csak jpg és png képekre fog működni. Még lehet bővíteni, csak plusz egy sor kell a htaccessbe, illetve a php-ban is kell két apró változtatás. Ha van ilyen irányú igény, szóljatok, vagy ha értitek a kódot, meg is próbálhatjátok megcsinálni.
Ezután hozzuk létre az image.php filet is a temp mappában, a tartalma:
PHP kód:
<?php
$domain = "www.example.com"; // A domain neved, www.domain.tld formában, lehet www. nélkül is
$original_images = "../watermark-nelkuli-kepek"; // Amire át fogod nevezni majd az images mappát, bármit írhatsz, de jegyezd meg
$path = str_replace('/', '', $_GET['i']);
$type = $_GET['type'];
$extension = ".".$_GET['ext'];
if(preg_match($domain, $_SERVER['HTTP_REFERER'])) { // Ez a kód 10. sora, lejjebb fontos lesz
if(file_exists($original_images.$path.$extension)) {
header('Content-type: image/'.$type);
readfile($original_images.$path.$extension);
} else {
echo('Nem létező kép!');
}
} else {
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
if(file_exists($path.$extension)) {
header('Content-type: image/'.$type);
readfile($path.$extension);
} else {
if(file_exists($original_images.$path.$extension)) {
$stamp = imagecreatefrompng('watermark.png');
if($type == "jpeg") {
$im = imagecreatefromjpeg($original_images.$path.$extension);
} elseif($type == "png") {
$im = imagecreatefrompng($original_images.$path.$extension);
}
imagecopyresized($im, $stamp, 0, 0, 0, 0, imagesx($im), imagesy($im), imagesx($stamp), imagesy($stamp));
header('Content-type: image/'.$type);
if($type == "jpeg") {
imagejpeg($im);
imagejpeg($im, $path.$extension);
} elseif($type == "png") {
imagepng($im);
imagepng($im, $path.$extension);
}
imagedestroy($im);
} else {
echo('Nem létező kép!');
}
}
}
?>
És akkor most jön egy olyan lépcsőfok, ami sajnos egyik megoldásban sem kikerülhetetlen, és elég nagy dilemmát tud okozni. Ugye arról volt szó, hogy a Googlnek más képet szolgálunk ki, mint amit a felhasználónak. A fenti kód megvalósítja, hogy azok, akiknek a HTTP_REFERER-jében (hivatkozó oldal) megtalálható a domain név, azoknak az eredeti képet szolgálja ki, de ez nem elég, mert vannak, akik privát módban böngésznek, és ez a bizonyos HTTP_REFERER egy üres karakterlánc (azaz nem lesz benne a domain név) - ők pedig a vízjelezett képet látják. Erre adódnak a következő megoldások, mindegyik a saját előnyükkel és hátrányukkal:
- A legegyszerűbb megoldás, hogy a kód 10. sorát módosítjuk a következőre:
PHP kód:
if(preg_match($domain, $_SERVER['HTTP_REFERER']) || !$_SERVER['HTTP_REFERER']) {
Ennek az eredménye az lesz, hogy mindenkinek a vízjel nélküli képet jelenítjük meg, akiknek a HTTP_REFERER-jében benne van a domain VAGY a HTTP_REFERER üres. Ha nem privát módban böngészik valaki, ott lesz a domain nevünk, ha privát módban, akkor üres lesz a HTTP_REFERER, így a mi oldalunkat nézők mindenképpen a vízjel nélkülit látják, ami jó. A hátrány ott van, hogy a Google-ben is a vízjel nélkülit látja az, aki privát módban böngészik, ezt pedig nem akarjuk természetesen. Megjegyzés: ebben a megoldásban ugyan azon URL-en szolgáljuk ki a felhasználókat és a keresőt, azaz semmi black hat nincs benne!
- A másik megoldás pedig az, hogy minden képmegjelenítéskor vizsgáljuk, hogy az adott látogató Google robot-e, és ha nem, akkor a jó URL-en jelenítjük meg a képeket. A probléma ott van, hogy ezt nem tehetjük be az images.php fileba, mert ha ezt megtennénk, akkor bárhonnan is kérik le a képet (akár a Google-ből), a vízjel nélkülit szolgálnánk ki. Ezért mindenhol, ahol képet jelenítünk meg, le kell cserélni a képet az új URL-re, hogyha nem Googlebottal van dolgunk. Ehhez szükségeltetik programozói tapasztalat / tudás, és sok helyen bele kell nyúlni esetleg az oldal forráskódjába, ezért ez a bonyolultabb megoldás. Aki tudja miről beszélek, az valószínűleg meg tudja oldani, aki nem, annak marad az előző pont. Azért egy röpke kis segítséget még rakok ide arra, hogyan ellenőrizzük, hogy a Google bot jár-e nálunk:
PHP kód:
if(preg_match("Googlebot", $_SERVER['HTTP_USER_AGENT'])) { /*Googlebot vagyok*/ }
Tehát aki az első megoldást választja, mert nem szeretne programozgatni, annak itt van a friss kód, immár lecserélve a 10. sor a megfelelőre:
PHP kód:
<?php
$domain = "www.example.com"; // A domain neved, www.domain.tld formában, lehet www. nélkül is
$original_images = "../watermark-nelkuli-kepek"; // Amire át fogod nevezni majd az images mappát, bármit írhatsz, de jegyezd meg
$path = str_replace('/', '', $_GET['i']);
$type = $_GET['type'];
$extension = ".".$_GET['ext'];
if(preg_match($domain, $_SERVER['HTTP_REFERER']) || !$_SERVER['HTTP_REFERER']) {
if(file_exists($original_images.$path.$extension)) {
header('Content-type: image/'.$type);
readfile($original_images.$path.$extension);
} else {
echo('Nem létező kép!');
}
} else {
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
if(file_exists($path.$extension)) {
header('Content-type: image/'.$type);
readfile($path.$extension);
} else {
if(file_exists($original_images.$path.$extension)) {
$stamp = imagecreatefrompng('watermark.png');
if($type == "jpeg") {
$im = imagecreatefromjpeg($original_images.$path.$extension);
} elseif($type == "png") {
$im = imagecreatefrompng($original_images.$path.$extension);
}
imagecopyresized($im, $stamp, 0, 0, 0, 0, imagesx($im), imagesy($im), imagesx($stamp), imagesy($stamp));
header('Content-type: image/'.$type);
if($type == "jpeg") {
imagejpeg($im);
imagejpeg($im, $path.$extension);
} elseif($type == "png") {
imagepng($im);
imagepng($im, $path.$extension);
}
imagedestroy($im);
} else {
echo('Nem létező kép!');
}
}
}
?>
Szóval már megvan a .htaccess és image.php fileunk. Nincs más dolgunk, mint készíteni egy watermark.png képet. Ez fog rákerülni a mi képünkre, mint vízjel. Mindegy mekkora, szét lesz nyújtva akkorára, amekkora maga a kép, de hogy ne legyen pixeles, érdemes nem piciben legyártani. Pl. egy 50% átlátszó rétek, rajta egy fehér felirat - én ezt használtam. A watermark.png is kerüljön a temp mappába.
És akkor most jön a varázslás.
Nevezzük át az image mappát arra, amit a $original_images-nek megadtunk értékül, pontosabban annak utolsó részére (a legutolsó / jel utáni rész). Majd ezek után nevezzük át a temp mappát image-re. Ezzel tehát semmi mást nem csináltunk, mint azt, hogy az image mappa mostmár a vízjeles képek helyéül szolgál, az onnan kért képek vízjelesek lesznek (kivéve, hogyha a mi oldalunkról kérték), és van egy másik mappa, amiben az eredeti képek vannak. Hogyha nem a mi oldalunkról (hanem pl. Googleből) lekérnek egy a vízjeles mappában lévő képet, akkor vízjeleset szolgálunk ki, egyébként pedig az eredetit.
Megoldás - lassabb eset:
Ez annyiban különbözik a fentiektől, hogy nem cseréljük meg a kép mappát. Itt most hozzunk létre egy új könyvtárat, mondjuk watermarked_images néven. Ebbe rakjuk be e a gyors megoldásnál írt .htaccesst, és ebbe rakjuk bele a gyors megoldásban írt image.php filet is. Az $original_images változónak adjuk meg az images mappa elérést (hogyha a mellé rakjuk az újat, akkor: "../images" -t kell oda írni). Ugyancsak rakjuk az új mappába a watermark.png filet.
Ezután pedig az összes képnél állítsuk be az új elérési útvonalat, ami nem má, minthogy a régiből az images könyvtárat lecseréljük a watermarked_images könyvtárra. Azt is lehet, hogyha tudunk programozni, hogy ezt csak Googlere szűrjük, és akkor azt kapjuk, mint a gyors megoldásban a bonyolultabb rész, ahol a bot látogatásakor más képet szolgálunk ki.
A gyors megoldás ajánlottabb, ezért annak elírása sokkal részletesebb, de az alapján lassú is elvégezhető.
Működés közben megtekinthető itt: https://www.google.hu/search?q=ork+karakterkép&tbm=isch
Ha van kérdés, tegyétek fel bátran, megpróbálok válaszolni. A következőkben pedig még csiszolom a kódot, mert implementálni szeretném az "eredeti kép megtekintése" gombra kattintásnál azt, hogy átirányítson arra az oldalra, ahol az eredeti kép található.
A megoldást bárki szabadon felhasználhatja, terjesztésnél kéretik a forrást (ezt a témát) belinkelni. Nem vállalok érte felelősséget, se biztonságilag, se azért, mert esetleg kivág a G az indexből (bár sok nagy oldal használ már ilyesmit). Megpróbáltam biztonságosra és lehető leggyorsabbra megírni, de majd itt az ügyesebbek javítanak, ha kell (pl. Geri), érdemes nyomon követni hát a témát a későbbiekben. Sok sikert!
Eredményekről örömmel venném, ha beszámolnátok.
Könyvjelzők