URL在大多數時候都是後端程式員關心的事情,但有的時候前端程式員也需要與之打交道,可能很多人都做過的一件事就是通過對 href 屬性的寫操作達到跳轉頁面的目的,不過這並不是今天要討論的全部話題。對於 URL,我們需要瞭解更多,因為我們的開發中可能會需要提取URL的部分資訊來做不同的事情,事實上這也是與後端互動的一種獨特的方式,當然這肯定是安全 的,當請求被返回,關於 url 的資訊就被記錄在了 Window 對象的 Location 屬性中,取值的結果並不隨著使用者手動修改地址欄中的字元而發生任何改變,這一點是很重要的。瞭解了這些內容,那麼我們從下面這張圖開始吧:
不要被那些色塊迷惑了,圖片中間那一行較長的字串是一個完整的 URL,它包含了一個 URL 中可能包含的任何部分:協議、網域名稱、連接埠號碼、路徑、參數、描點。在 JavaScript 中,擷取到這一行字串的方法是訪問 window.location.href,href屬性包含了一個頁面完整的 URL。如果想得到 URL 中某一部分的值,我們可以通過複雜、繁瑣的Regex來解析這個完整的 URL,不過更方便的辦法是通過 location 的其他屬性來擷取。比如 location 的 protocol 屬性中記錄了帶冒號的協議名,pathname 屬性儲存區著路徑名,這些屬性是 href 的分離,給開發人員帶來了很多方便。下面的表格中羅列了 location 下所有的屬性,以及他們各自記錄的值。如果不能理解表格中的內容,那麼上面那張圖中的色塊和文字,形象地描述了各屬性在 URL 中對應的位置。
屬性 |
值 |
href |
完整的 URL |
protocol |
協議 |
hostname |
主機名稱 |
host |
主機名稱加連接埠號碼 |
port |
的連接埠號碼 |
pathname |
當前 URL 的路徑部分 |
search |
URL 的查詢部分 |
hash |
#開始的錨 |
值得注意的是,上面的屬性都是可寫的,這表示我們可以通過 JavaScript 改變他們的值。這些屬性大都一目瞭然非常簡單,唯有 search 部分是比較麻煩的,search部分是以 GET 方式傳給背景參數,以 ? 開始,& 作為分隔字元,= 賦值的序列化的字串,如此一來通過 location.search 得到的值往往並不是想要得到的最終結果,通過 search 的結構來分析,我們可能更想要得到的結果是一個包含明確對應關係的關聯陣列。於是我們需要對 location.search 中得到的字串進行進一步的處理。
function getArgs() { var args = {}; var query = location.search.substring(1); // Get query string var pairs = query.split("&"); // Break at ampersand for(var i = 0; i < pairs.length; i++) { var pos = pairs[i].indexOf('='); // Look for "name=value" if (pos == -1) continue; // If not found, skip var argname = pairs[i].substring(0,pos); // Extract the name var value = pairs[i].substring(pos+1); // Extract the value value = decodeURIComponent(value); // Decode it, if needed args[argname] = value; // Store as a property } return args; // Return the object}
上面的代碼來自於《JavaScript 權威指南》一書中。getArgs 方法不接收參數,它主動提取 URL 中的 search 部分加以解析,並返回一個 JSON。例如我們最開始那張圖片中的 URL ,使用 getArgs 方法將會得到下面的結果:
var search = { "q" : "123", "a" : "321"}
這樣,關於 URL 的所有資訊都能得到一個非常明確的結果,很簡單。不過更推薦 Doomain 的方法,他的方法使用Regex解析URL,達到的目的一致,但運行效率更高,代碼也更加簡潔。關於這一方法的代碼在本文評論的13樓,點擊這裡快速到達。