Cet article vous présente les problèmes liés à l'anti-hotlinking PHP. Le contenu principal est d'expliquer le principe du Referer et la méthode de mise en œuvre de l'anti-hotlinking d'image. J'espère que cela sera utile aux amis dans le besoin~
1. . Image anti-hotlinking
Dans certains grands sites Web, tels que Baidu Tieba, les images de ce site adoptent des règles anti-hotlinking, de sorte que l'utilisation du code suivant provoquera des erreurs. [Recommandation : Tutoriel vidéo PHP]
Code simple :
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> <link rel="stylesheet" href=""> </head> <body> <!--引用一张百度贴吧的图片--> <img src="http://imgsrc.baidu.com/forum/pic/item/03a4462309f79052204229be04f3d7ca7acbd5d5.jpg"/ alt="PHP+Referer réalise la prévention des liens hypertextes d'image ! (Joint avec un exemple de code)" > </body> </html>
Problèmes :
La raison de l'erreur
est principalement que les images de ce site adoptent des règles anti-hotlinking. cette règle est également relativement simple. Vous le saurez dès que je vous le dirai. La raison principale est que lorsque le site apprend qu'il y a une demande, il déterminera d'abord les informations contenues dans l'en-tête de la demande s'il y a des informations sur le référent. dans l'en-tête de la demande, il déterminera ensuite si les informations de l'en-tête Referer sont basées sur ses propres règles. Si les exigences sont remplies, les informations Referer sont l'adresse source de la demande d'image.
Demander des informations d'en-tête dans le navigateur :
(1) Utilisez normalement Baidu Tieba pour afficher les informations d'en-tête de demande de l'image
(2) Informations d'en-tête de mon code
Je crois que les lecteurs voient ceci , je comprends pourquoi mon code ne peut pas accéder à l'image, mais affiche un avertissement pour le hotlinking. Parce que nos informations d'en-tête Referer sont différentes de celles de Baidu Tieba. Lorsque ma demande est envoyée, le site vérifie les informations d'en-tête Referer, dès que je le fais. J'ai vu que la source n'était pas ce site, j'ai été redirigé vers une autre photo.
Configurez la protection des liens hypertexte des images pour votre site :
(1) Activez le module mod_rewrite dans le serveur Web
#LoadModule rewrite_module modules/mod_rewrite.so, //Supprimez le # devant, puis redémarrez le serveur
( 2) Dans le site Web ou le répertoire qui doit être protégé contre le vol, écrivez un fichier .htaccess et spécifiez les règles anti-hotlinking
Étapes :
Créez un nouveau fichier .htaccess et utilisez la méthode de sauvegarde sous Windows pour créer. un nouveau fichier.
Trouvez le manuel dans Utiliser un jugement régulier
pour spécifier les règles dans le fichier .htaccess :
S'il s'agit d'une ressource d'image et que les informations d'en-tête du référent proviennent de ce site, utilisez
pour réécrire les règles comme suit :
En supposant que mon serveur est localhost, la signification de la règle est , si la demande concerne une ressource image, mais que la source de la demande ne provient pas de ce site, elle sera redirigée vers une image no.png dans le répertoire actuel
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} .*.(jpg|jpeg|png |gif) [NC]
RewriteCond %{HTTP_REFERER} !localhost [NC]
RewriteRule .* no.png
Visites de localhost :
Visites d'autres sites :
À ce stade, nous avons fini d'apprendre les connaissances sur l'anti-hotlinking, mais ne vous précipitez pas puisqu'il s'agit d'un en-tête de requête, bien sûr, cela peut l'être. forgé. Parlons des règles anti-hotlinking.
2. Anti-hotlinking
Mon serveur est configuré avec un anti-hotlinking d'images. Je vais maintenant l'utiliser pour expliquer l'anti-hotlinking. Si nous rencontrons un site qui utilise la technologie anti-hotlinking lors de la collecte d'images. Vous pouvez forger un en-tête Referer lors de la collecte d’images.
Le code suivant télécharge une image à partir d'un site configuré avec une protection contre les liens hypertextes d'image.
<?php /** * 下载图片 * @author webbc */ require './Http.class.php';//这个类是我自己封装的一个用于HTTp请求的类 $http = new Http("http://localhost/booledu/http/apple.jpg"); //$http->setHeader('Referer:http://tieba.baidu.com/');//设置referer头 $res = $http->get(); $content = strstr($res,"\r\n\r\n"); file_put_contents('./toutupian.jpg',substr($content,4)); echo "ok"; ?>
Le résultat du téléchargement sans ajouter les informations d'en-tête du référent :
Le résultat du téléchargement avec les informations d'en-tête du référent :
En conséquence, lorsque vous voyez cela, vous devriez être en mesure de voir comment empêcher le hotlinking, en fait, il s'agit d'ajouter des informations d'en-tête de référent, alors, où puis-je trouver les informations d'en-tête de référent pour chaque site ? Cela devrait être compris grâce à la capture et à l’analyse des paquets !
3. Classe de requête HTTP encapsulée
<?php /** * Http请求类 * @author webbc */ class Http{ const CRTF = "\r\n"; private $errno = -1; private $errstr = ''; private $timeout = 5; private $url = null;//解析后的url数组 private $version = 'HTTP/1.1';//http版本 private $requestLine = array();//请求行信息 private $header = array();//请求头信息 private $body = array();//请求实体信息 private $fh = null;//连接端口后返回的资源 private $response = '';//返回的结果 //构造函数 public function __construct($url){ $this->connect($url); $this->setHeader('Host:'.$this->url['host']);//设置头信息 } //通过URL进行连接 public function connect($url){ $this->url = parse_url($url);//解析url if(!isset($this->url['port'])){ $this->url['port'] = 80; } $this->fh = fsockopen($this->url['host'],$this->url['port'],$this->errno,$this->errstr,$this->timeout); } //设置请求行信息 public function setRequestLine($method){ $this->requestLine[0] = $method.' '.$this->url['path'].' '.$this->version; } //设置请求头信息 public function setHeader($headerLine){ $this->header[] = $headerLine; } //设置请求实体信息 public function setBody($body){ $this->body[] = http_build_query($body); } //发送get请求 public function get(){ $this->setRequestLine('GET');//设置请求行 $this->request();//发送请求 $this->close();//关闭连接 return $this->response; } //发送请求 private function request(){ //拼接请求的全部信息 $reqestArr = array_merge($this->requestLine,$this->header,array(''),$this->body,array('')); $req = implode(self::CRTF,$reqestArr); //print_r($req);die; fwrite($this->fh,$req);//写入信息 //读取 while(!feof($this->fh)){ $this->response .= fread($this->fh,1024); } } //发送post请求 public function post($body = array()){ //设置请求行 $this->setRequestLine("POST"); //设置实体信息 $this->setBody($body); //设置Content-Type $this->setHeader('Content-Type:application/x-www-form-urlencoded'); //设置Content-Length $this->setHeader('Content-Length:'.strlen($this->body[0])); //请求 $this->request(); $this->close();//关闭连接 return $this->response; } //关闭连接 public function close(){ fclose($this->fh); } } //测试get // $http = new Http("http://news.163.com/16/0915/10/C10ES2HA00014PRF.html"); // $result = $http->get(); // echo $result; //测试post /*set_time_limit(0); $str = 'abcdefghijklmnopqrstuvwxyz0123456789'; while(true){ $http = new Http("http://211.70.176.138/yjhx/message.php"); $str = str_shuffle($str); $username = substr($str,0,5); $email = substr($str,5,10).'@qq.com'; $content = substr($str,10); $message = "发表"; $http->post(array('username'=>$username,'email'=>$email,'content'=>$content,'message'=>$message)); //sleep(0.1); }*/ ?>
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!