首先說一下這個探討的原因,相信大多數站長關心的不只是技術本身,而是如何實現更好的運營。在網上有太多關於絕對地址與相對地址影響 SEO 的文章。觀點主要是以下幾方面:
1. 使用絕對地址有利於 SEO 。
2 使用相對地址方便站點的變更。
首先簡單介紹一下絕對地址與相對地址,我們開啟 discuz 的官方站點 http://www.discuz.net/ 然後檢視原始碼。去找到 logo 的這段話,是這樣的
- <a href="./" title="Discuz! 官方站"><img src="static/image/common/logo.png" alt="Discuz! 官方站" border="0" /></a>
這個 a 標籤的 URL 地址就是相對地址, ./表示的是當前目錄, 也就是 http://www.discuz.net/ ,同樣我們看到了圖片的地址 static/image/common/logo.png 也是相對地址,真正的地址是 http://www.discuz.net/static/image/common/logo.png
接下來搜尋"設定",我們將找到這樣的一個標籤<a href="http://www.discuz.net/home.php?mod=spacecp"> 設定</a> 這裡使用的就是絕對地址。
先深入介紹一下相對地址,我們發現相對地址只是寫了後面的一部分,那前面的內容是怎麼得到的呢。剛才我們在 discuz 的官網上訪問的那個頁面,所以前面的那一部分就是 http://www.discuz.net/了,好,為了驗證這個猜想,我們寫一個簡單的頁面
檔名叫 url.html,內容如下
- <a href="./" ><img src="static/image/common/logo.png" /></a>
然後放在另一個站點下,這裡我以自己的一臺虛擬機器為例,訪問地址為 http://虛擬機器地址/test/url.html
然後我們發現,圖片是無效的,連結點了以後是 http://虛擬機器地址/test/ 說明相對地址相對的是以當前的 URL,換句話說相對地址的基準是當前的 URL 。
同樣,我們把檔案儲存在自己的個人電腦裡,如 F:dzurl.html , 然後用瀏覽器直接開啟這個檔案,將會看到位址列為 file://F:dzurl.html,沒有顯示圖片,點選之後進入了檔案所在的目錄 file://F:dz 。
接下來我們修改一下這個檔案內容
- <html>
- <head>
- <base href="http://www.discuz.net/">
- </head>
- <body>
- <a href="./" ><img src="static/image/common/logo.png" /></a>
- </body>
- </html>
然後再次訪問 http://虛擬機器地址/test/url.html(或者是 F:dzurl.html 也可以看到相同的效果) ,我們將能看到 discuz 的 logo,點一下也跳轉到了官方論壇。
細心的你也許發現了, 在<head> 段多了一個標籤 <base href="http://www.discuz.net/"> 正是這個標籤,設定了相對地址的基準 URL,
關於相對地址的總結如下:如果頁面中沒有<base> 標籤來設定,將以當前 URL 為基準。如果設定了<base> 將以此為準, 用來拼接頁面中的相對地址。
關於絕對地址,就容易很多,不需要拼接,直接訪問。
discuz 預設採用的是相對地址, 並且設定了<base> 標籤。
下面重點講一下<base> 標籤的設定過程。
我們開啟 template/default/common/header_common.htm 這個模版檔案,將會看到<base
href="{$_G['siteurl']}" />
那麼 $_G['siteurl'] 是在哪裡設定的呢, 我們開啟檔案 source/class/class_core.php,查詢 siteurl,有一行
是這麼寫的.
- $_G['siteurl'] = htmlspecialchars('http://'.$_SERVER['HTTP_HOST'].$sitepath.'/');
更詳細的程式邏輯不在此細說,基本意思就是取得當前檔案所在的路徑。在本地的測試機上可能是這樣的 http://localhost/x2/ 對應官方的論壇就是這樣的 http://www.discuz.net/ 這個值最終出現在了頁面中的<base> 標籤裡。
為了說明如何實現絕對地址,還需要詳細講一下 dz 的頁面是如何輸出的
我們還以官方論壇首頁為例進行說明, 大體流程如下
[入口檔案]->[初始化設定]->[模組檔案]->[載入模板]->[執行模板]->[輸出準備]->[正則替換]->[內容輸出]
1. 訪問 http://www.discuz.net/forum.php 載入入口檔案 forum.php
2. 在最後一行之前的所有程式碼, 都是做初始化的工作
3.forum.php 最後一行程式碼,載入了模組檔案,這裡的 $mod 值為 index
- require DISCUZ_ROOT.'./source/module/forum/forum_'.$mod.'.php';
4.forum_index.php 檔案前面的部分都是模組檔案的資料處理, 取得版塊資訊。
5.forum_index.php 最後一行執行程式碼 include template('diy:forum/discuz:'.$gid); 將透過 discuz 系統函式載入模版。
6. 在 function_core.php 中的函式 template() 取得了所需的模板地址, 為 1_diy_forum_discuz.tpl.php,這裡面是透過靜態模板生成的 php 程式碼,將內容與模版結合在一起。
7.1_diy_forum_discuz.tpl.php 的最後一條 php 語句為<?php output();?> 正是這句話完成的輸出準備與最終輸出。
function_core.php 中的函式 output(),首先取得了頁面內容。
8. 透過函式 output_replace() 完成了正則替換.(我們要講的重點也在這裡)
9. 最終, 頁面輸出, 大功告成。
output_replace() 函式與 cache_setting.php 中 $_G['setting']['output'] 的設定。
output_replace() 函式的前半部分是應用域名替換,後面部分是靜態化的實現。與之對應,cache_setting.php 中設
置 $_G['setting']['output'] 的時候 $output['str'] 是用來替換應用域名 $output['preg'] 是用來實現靜
態化。
下面,我們進入後臺-> 全域性-> 域名設定-> 應用域名
在這裡什麼都不填的話,$output['str'] 是空的,在 output_replace() 中也不會進行應用域名的替換。
如果只填寫了預設域名,那麼相當於所有的應用都填的預設域名。 $output['str'] 的值,經過 output_replace() 的替換,整個站點
的連結都變成了絕對地址。因為替換規則就是將<a href="forum.php"換成了<a
href="http://yourdomain/forum.php",預設的論壇入口就是這 4 個 portal.php forum.php
group.php home.php,如此一來實現了絕對地址,
如果只填寫某一項應用的域名而不填預設,程式會將其他幾個應用設定為當前域名。
做好了上面的準備工作,假如我們填寫了預設域名,output_replace() 將會把所有的 php 入口檔案前面加上我們設定好的域名,從而形成絕對 URL 地址,下面一步是把 URL 地址靜態化。接下來就是頁面輸出,呈在了瀏覽器中。