短網址司空見慣,比如說下面這些
http://dwz.cn/CSW6Y => http://www.cnblogs.com/iforever/p/4313704.html,
http://dwz.cn/CSWuP => http://www.cnblogs.com/iforever/p/4279006.html ,等等
訪問這些網址的時候,前後一對的指向同一個頁面,我這裡只是在舉例子,這些短網址在weibo或者類似的社交網絡中經常見到,由於原始鏈接地址特別長,這個時候短網址就會大顯威力,簡短好記,但也有他的缺點,比如說短網址不一定直接看出網址中的一些信息(在長網址中是可以看到一些信息的)。
整天接觸這個,以至於在還沒有真正弄明白他的原理的時候就在思想中烙下了“沒什麼”的烙印,這就錯過了一些知識,這種情況在心理學上應該叫心裡暗示吧,有人知道是這樣嗎?
首先我猜測這個是通過重定向實現的,dwz.cn是一個服務器,用來接收一些短網址,這些短網址是經過dwz.cn處理之後的,在dwz.cn中有該短網址對應的長網址的記錄,然後從數據庫中獲取短網址對應的長網址,然後302重定向。看看具體是不是這樣的。
通過浏覽器訪問http://dwz.cn/CSW6Y,對請求進行分析(這裡使用chrome的調試工具,也可以使用wireshark之類的工具),可以得到下面的數據:
name: abit version: 1 handle: - rewrite: if (!-d && !-f && path ~ "/(.*)$") goto "do.php?url=$1&act=out"
handle:後面的就是rewrite規則,新浪雲的具體的詳細規則到這裡看http://sae.sina.com.cn/doc/php/runtime.html#php-app-config,很簡單,nginx、apache的配置也類似。
重定向完成之後還有一個要注意的地方就是在傳遞參數的時候要進行urlencode,重定向之前要用urldecode。在未使用urlencode的時候傳遞url類型的參數,在獲取的時候可能丟掉部分信息,因此在生成短鏈接之前傳遞參數的時候要將url進行escape處理,將特殊字符串進行編碼,在訪問短鏈接處理的時候需要對編碼的url進行urldecode處理,還原成正常的鏈接,否則在header跳轉的時候不會把該鏈接當成一個正常的url,跳轉之後會把該url附加的之前頁面的主機後面類似http://abit.sinaapp.com/www.cnblogs.com,可能會出現錯誤,因此,這裡要特別注意。
sae的在重定向的時候會有一個問題,會將雙反斜線自動過濾為一個,例如從http://abit.sinaapp.com/到http:/abit.sinaapp.com/,注意,這裡少了個反斜線,這在處理的時候要特別注意,不然可能會遇到不必要的麻煩。
主要的處理部分
<?php class snapshotUrl{ //進行編碼的數據庫,沒6位二進制數對應一個字符,一共需要64位,因此選取 //52+10+2個特殊字符 private static $basedb = array( '(',')','a','b','c','d', 'e','f','g','h','i','j', 'k','l','m','n','o','p', 'q','r','s','t','u','v', 'w','x','y','z','A','B', 'C','D','E','F','G','H', 'I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5', '6','7','8','9', ); private function long2short($url){ $hex = md5($url); $out = ''; $hex = 0x7FFFFFFF & (1 * ('0x'.substr($hex, 0, 8))); for($i=0; $i<5; $i++){ $index = 0x3f & $hex; $out .= self::$basedb[$index]; $hex = $hex>>6; } return $out; } public function retJson($arr){ return json_encode($arr); } //對url進行映射保存 public function dispose($url, $act){ $mysql = new SaeMysql(); switch ($act) { case 'in': $short = $this->long2short($url); $url = addslashes($url); $sql = "insert into `tiny_url`(`short`,`long`) values ('{$short}','{$url}')"; $mysql->runSql($sql); if($mysql->errno() != 0){ echo "生成失敗"; }else{ echo "http://abit.sinaapp.com/{$short}"; } break; case 'out': if(strlen($url) > 5) echo $this->retJson(array("code"=>"-1","msg"=>"沒有這條記錄")); $sql = "select * from `tiny_url` where `short`='{$url}' limit 1"; $data = $mysql->getData($sql); if(!$data) { echo $this->retJson(array("code"=>"-1","msg"=>"沒有這條記錄")); }else{ $location = urldecode($data[0]['long']); header("Location: {$location}"); exit(); } break; default: # code... break; } } } $url = isset($_GET['url']) ? $_GET['url'] : null; $act = isset($_GET['act']) ? $_GET['act'] : null; $snapshotUrl = new snapshotUrl(); if($url === null || $act === null) echo $snapshotUrl->retJson(array("code"=>"-1","msg"=>"參數錯誤")); $snapshotUrl->dispose($url, $act);
我做了個可以測試的小網頁:
http://abit.sinaapp.com/有興趣的可以試試
本文版權歸作者iforever([email protected])所有,未經作者本人同意禁止任何形式的轉載,轉載文章之後必須在文章頁面明顯位置給出作者和原文連接,否則保留追究法律責任的權利。