QQ空间的“神奇”图片
昨天女友說遇到了一個奇怪的問題,就是在別人的QQ空間的轉載上看到了自己的名字,頭像,問我是怎么回事。晚飯后,閑來無事,想到那個問題,就讓女友打開那個看到自己頭像,名字的網頁(因為本人幾乎不上空間,所以空間這方面近乎白癡)。看到她說的那個地方是一張圖片,使用chrome審查元素發現這張圖片來源于一個PHP文件,而且這個文件不是QQ空間自帶的:
http://qq.sennvwu.com/qzone/do.php
試圖獲取一下,無功而返。因為PHP的運行都是在服務器端運行的,而用戶看到的網頁則是PHP的運行結果,可以說跟源文件沒有一毛錢關系,這就很難辦了!
想了一下,應該是這樣一個流程:用戶查看這個文章(初始是一張圖片,no.png)——用戶點擊后文章內調用定的PHP文件——PHP文件獲取當前頁面的QQ號碼——然后通過騰訊的開放接口查詢用戶的名字,頭像并使用其他開放接口獲取查看文章用戶的ISP——將獲取的頭像,名字,ISP等信息加上一段話生成一張圖片——將這張圖片返回到用戶查看界面——用戶看到神奇的圖片。
在網上找了一些資料(畢竟對PHP了解的只是皮毛),發現有大神已經全部搞定,還附帶了源碼,故轉載至此!
以下是轉載文章內容:
昨晚上偶然看到個比較坑爹的日志,正文有一張圖片,在好友動態列表查看的時候可以顯示自己(不是發日志的好友,是你自己)的頭像和QQ號碼、昵稱。正文的文字稱,這是“本年度最給力神奇魔力日志(轉載會看到你最熟悉的身影)”,并且在文章底部附加了一個發廣告的QQ號碼。
?
由于這張坑爹圖片的存在,文章轉發量短短三天內過千。這招可比那些瘋狂加群發廣告的來的更有創意和殺傷力,轉載傳播圖片(包括日志當中的廣告)的人幾乎是全網用戶(跟所謂病毒營銷差不多了)。好奇的話可以看這篇日志最初來源:hXXp://user.qzone.qq.com/732678621/blog/1363502247
一看就知道是檢測referer的把戲。早在幾年前BBS還在流行的時候,很多人設置的簽名圖具有天氣預報、客戶端信息(瀏覽器、操作系統、IP所在地之類)、隨機笑話、倒計時等五花八門的功能。這都得益于服務器端腳本的圖像處理功能。而客戶端的檢測則是基于HTTP請求中的UserAgent和Referer等信息。
但是印象中QQ空間為了防止referer潛在的安全問題和防止圖片被防盜鏈瞎了很大功夫,凡是發表到QQ空間的日志,正文都會把引用到的所有第三方圖片資源緩存到騰訊的云端上。所以直接在日志正文中引用的圖片,是不會提交REFER到我們的服務器腳本上的。
文中特別稱,“請轉載后用電腦進入個人中心看”。為什么要特別說明是“個人中心”呢?我刷新了好久的動態,終于看到了圖片所說的效果。頁面生成的DOM代碼為:
imgsrc="http://qq.sennvwu.com/qzone/do.phponload="QZFL.media.reduceImage(0,400,300,{trueSrc:'http:\/\/qq.sennvwu.com\/qzone\/do.php',callback:function(img,type,ew,eh,o){var _h = Math.floor(o.oh/o.k),_w = Math.floor(o.ow/o.k);if(_w<=ew && _h<=eh){var p=img.parentNode;p.style.width=_w+'px';p.style.height=_h+'px';}}})"
?width="400">
?
原來QQ空間還是會顯示源地址的圖片的,僅限于在“個人中心”。這時候請求圖片附帶的HTTP_REFERER的值為
http://user.qzone.qq.com/QQ號/infocenter
號碼就是這樣提取到的。如果REFERER不滿足條件,這個php將在header中發送Location跳轉到同一目錄下的no.png。
那么后臺是如何取到QQ頭像、昵稱等信息的呢?我Google到了一個騰訊的WebService接口:
http://base.qzone.qq.com/fcg-bin/cgi_get_portrait.fcg?uins=QQ號
不需要任何憑證信息即可獲取uins指定的QQ號碼的頭像、昵稱信息,返回的格式為JSON。另外上面的圖片還有一個顯示地理位置和ISP的功能,這個就比較常見了。我找到了一個比較好用的接口,來自TB:
http://ip.taobao.com/service/getIpInfo.php?ip=127.0.0.1
格式同樣也是JSON。
接下來實現這個效果就比較簡單了,通過REFERER檢測用戶的QQ號碼,然后在后臺下載頭像、昵稱等信息,用GD函數繪制上圖片,返回客戶端。
我也折騰了一個‘神奇圖片“發到空間,居然捉弄了一群人。下面是php語言的實現代碼。為了減少后端的流量,對下載的頭像做了緩存處理:
?
<?php
error_reporting(0);
ob_start();
header('Content-Type: p_w_picpath/png');
define('IMG_NO', "no.png"); #剛開始顯示的提示信息
define('IMG_BACKGROUND', "background.png");
define('IMG_WIDTH', 400);
define('IMG_HEIGHT', 128);
define('FONT_NAME', "AdobeHeitiStd-Regular.otf"); #字體文件名
define('CACHE_PATH', rtrim(realpath("./cache"), '/').'/'); #緩存目錄
define('CACHE_EXPIRE', 60*60); #緩存時間,單位秒
#(!is_dir(CACHE_PATH) && is_writable(CACHE_PATH)) || die;
/*
$remote: 遠程URL
$local: 本地緩存路徑
$expire: 過期時間。為-1時,永久不更新緩存
*/
function load_from_cache($remote, $local, $expire = CACHE_EXPIRE, $as_path = false) {
#過濾潛在的危險字符
$local = preg_replace("/[.\/\\\?\*\'\"\|\:\<\>]/", "_", $local);
$cache = CACHE_PATH.$local;
#查找緩存
if(file_exists($cache) && ($expire = -1 || filemtime($cache) - time() < $expire))
return $as_path ? $cache : file_get_contents($cache);
#文件不存在或緩存過期,重新下載
$content = file_get_contents($remote);
file_put_contents($cache, $content);
return $as_path ? $cache : $content;
}
/*
返回客戶端信息。
*/
function client_info() {
$url = "http://ip.taobao.com/service/getIpInfo.php?ip=";
$ip = ($_SERVER["HTTP_VIA"] && $_SERVER["HTTP_X_FORWARDED_FOR"] ??
$_SERVER["HTTP_X_FORWARDED_FOR"] : $_SERVER["REMOTE_ADDR"]);
$info = explode('"', load_from_cache($url.$ip, $ip, -1));
$string = $info[7].$info[23].$info[31].$info[47];
return json_decode('"'.$string.'"');
}
$referer = $_SERVER['HTTP_REFERER'];
#$referer = "http://user.qzone.qq.com/123456789/infocenter";
$pattern = "/http:\/\/user.qzone.qq.com\/(\d+)\/infocenter/";
if(preg_match($pattern, $referer, $matches)) {
#獲取QQ號碼
$uin = $matches[1];
$info = explode('"', load_from_cache(
"http://base.qzone.qq.com/fcg-bin/cgi_get_portrait.fcg?uins=".$uin, $uin));
$avatar = $info[3];
$nickname = iconv("GBK", "UTF-8//IGNORE", $info[5]);
$client = client_info();
#重點來了,生成圖片
try{
$im = p_w_picpathcreatefrompng(IMG_BACKGROUND);
? ?#繪制頭像
? ?$avatar_file = load_from_cache($avatar, $uin.".jpg", 60*60*24, true);
? ?$im_avatar = p_w_picpathcreatefromjpeg($avatar_file);
p_w_picpathcopymerge($im, $im_avatar, 14, 14, 0, 0, 100, 100, 100);
p_w_picpathdestroy($im_avatar);
#繪制文字
$blue = p_w_picpathcolorallocate($im, 0, 0x99, 0xFF);
$white = p_w_picpathcolorallocate($im, 0xFF, 0xFF, 0xFF);
$texts = array(
array(12, 148, 40, $white, $uin),
array(18, 125, 70, $blue, $nickname),
array(16, 125, 100, $blue, $client)
);
foreach($texts as $key=>$value) {
p_w_picpathttftext($im, $value[0], 0, $value[1], $value[2], $value[3], FONT_NAME,?
mb_convert_encoding($value[4], "html-entities", "utf-8")); #解決亂碼問題
}
p_w_picpathpng($im);
p_w_picpathdestroy($im);
header("Content-Length: ".ob_get_length());
? ? ? ? ob_end_flush();
} catch (Exception $e) {
? ?#die($e->getMessage());
? ?$error = true;
}
} else {
$error = true;
}
if($error){
header('Content-Length: '.filesize(IMG_NO));
? ? echo file_get_contents(IMG_NO);
}
?
?
?
?
?
轉載于:https://blog.51cto.com/hero2012/1167795
總結
以上是生活随笔為你收集整理的QQ空间的“神奇”图片的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Microsoft和AWS推出免费的云优
- 下一篇: Firefox 扩展开发 install