網頁短連結
網頁短連結是指將原本較長的網址轉化成較短的網址,從而便於使用者的記憶與社交軟體上的傳播。很多網際網路公司都提供了生成短連結的服務,比如新浪微博短網址服務等,本文就來聊聊實現短連結服務的基本原理。
我們不妨先來看一下短連結服務的整個流程,以前面提到的微博短網址服務為例。使用者輸入想要縮短的長網址,轉化後得到一個以http://t.cn
開頭的短網址,然後使用者將該連結通過微信或者微博等方式分享給朋友,其他人點選之後即可進入原本長網址所對應的頁面。整個流程如下圖所示:
從圖中可以很清楚地看到,實現短連結服務的關鍵是兩個步驟:1、如何把一個任意長的字串轉化成一個較短的字串;2、從短網址如何還原出長網址。第一個問題很容易讓人想到雜湊演算法,通過一定的方式將任意長的文字轉化成一個固定長度的字串,只要目標字串的長度適當,那麼不同的輸入幾乎不可能對應同一個字串。不過這麼做有個缺點就是無法從得到的結果還原輸入的字串,因此不適用於我們的場景。但基於雜湊演算法的思想,我們可以設計一種以多進製為基礎
具體而言,我們可以建立一個用於儲存長網址的資料表,比如就叫Url,這張表很簡單,只需要兩個欄位,一個主鍵
用於儲存id
,一個url
欄位用於存放原始的長網址,每個長網址都在這張表有一條記錄。當進行長網址轉換時,先檢查資料表中是否存在該長網址,若是直接獲取該記錄的id
,否則在資料表中建立一條新記錄,並返回其id
。對於這個id
,我們可以得到一個多進製表示下的新值,比如在以“0-9a-z”這36個字元表示的36進制中,一億
這個數字可以被表示成1njchs
,只需要6個字元即可,將這6個字元拼接到準備好的域名後即可得到一個對應的短網址返回給使用者。由於一億個網址只需要6個字元,因此這種方式足夠滿足大部分網站的需求。
而當用戶點選了我們生成的短網址後,只需要將代表多進位制的這部分提取出來,還原成十進位制的數字後查表即可得到原始的長網址,再根據網址做一個重定向即可讓使用者訪問到原始的網頁。具體的實現可以參考下面的typescript
程式碼
// 將原始的長連結通過36進位制轉化為短連結
export async function long2short(url: string) {
if (!url.startsWith('http://') && !url.startsWith('https://')) {
throw new Error('Invalid url');
}
if (url.startsWith(config.shortLinkBaseUrl)) {
return url;
}
let item = await Url.getByUrl(url);
if (!item) {
item = await Url.create(url);
}
return config.shortLinkBaseUrl + item.id.toString(36);
}
// 將短連結還原為真實的長連結
export async function short2long(url: string) {
let item = await Url.select(Number.parseInt(url, 36));
if (!item) {
throw new Error('Invalid url');
}
return item.url;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
這裡的config.shortLinkBaseUrl
也就是我們用來做短連結服務的域名,在前面的例子中就是http://t.cn
,我們需要在這個域名對應的伺服器內實現短連結的服務,同時這個域名本身不能太長,否則就失去了它的意義。另外還有一點值得注意,就是在根據長網址去資料表查詢它是否存在時,因為長網址可以任意長,因此直接用它作為索引在資料表中查詢的話效率較低,可以考慮在表中增加一個hash
欄位,儲存長網址的雜湊值,並通過查詢雜湊值來判斷條目是否存在,提高查詢的效率。
以上就是短連結服務的基本實現方法,最核心的其實就是多進位制
的使用,有興趣的朋友可以自己動手試試看,有任何問題歡迎留言交流。