關於URL中'?'和'#'的作用和歷史


0.考考你

  請觀察下面幾個URL

  http://www.xxx.com/page?a=1&b=2

  http://www.xxx.com/page#xxx

  http://www.xxx.com/#/page?a=1&b=2

  http://www.xxx.com/?a=1&b=2#/page?c=3

 

  提問

  - '?'是什么意思?

  - '&'是什么意思?

  - '#'是什么意思?

  - 第一個和第三個URL有什么區別?

  - 第四個URL是什么意思?

 

  也許前兩個問題你可以脫口而出地回答上來,但后面的問題你不一定能答出來,如果你沒法回答,或者即使知道答案但還是不太懂原理,感覺似懂非懂,那么請閱讀這篇文章。本文將詳細介紹上面那些符號的意義,以及他們的演變歷史,下面開始!

 

1.什么是'?'和'&'

  首先來講講'?''&',大家都知道,這是URL參數,一般英文叫"query string",直譯也叫"查詢字符串"。我們都知道"http://www.xxx.com/page"一般是指向一個頁面的地址,而URL參數則是給這個頁面添加了訪問參數,例如我們可以在頁面地址后面加上"?id=aaa&group=bbb"來記錄當前需要訪問的記錄id為aaa,分組id為bbb。完整示例如下:

  http://www.xxx.com/page?id=aaa&group=bbb

 

  由'?'和'&'表示的URL參數從最初提出一直到現在,其作用和用法始終沒有變過,而'#'則在web發展的漫長的歲月中前前后后改變過了多次。下面我們來詳細講講'#'

 

2.'#'最初被提出時的作用

  '#'的名字為hash,最初被提出時被用於錨點定位功能。所謂錨點定位,意思是讓瀏覽器定位到頁面上的某個元素位置處。例如,某頁面上有很多很多的元素,其中有一個元素的id為"div1",那么,我們只要在URL地址里加上"#div1"就可以讓瀏覽器滾動到這個元素的位置處。示例如下:

  http://www.xxx.com/page#div1

  

  錨點定位功能不單單只在頁面打開時會生效,還可以動態生效,比如你可以先在地址欄上使用"#div1"定位到div1的位置處,然后再手動修改地址欄改成"#div2",敲下回車,瀏覽器就能定位到div2的位置處。

 

  Try it yourself ! 自己動手試試!

  - 打開這個地址https://www.rplugin.com/demos/demo1#section3

  - 在瀏覽器地址欄中把"section3"改成"section8",敲回車

  你將看到的效果是,當你首次打開上面的地址時,頁面默認滾動到了第3章,而當你修改了地址欄中的hash值時,頁面又滾動到了第8章。

  請注意這里有一個細節!當你把"section3"改成"section8",敲回車時,頁面沒有重載動作,而只是做了滾動動作

  

  下面我們再來看URL參數在變更時又是什么效果

  - 打開這個地址https://www.rplugin.com/demos/demo1?id=aaa

  - 在瀏覽器地址欄中把"aaa"改成"bbb",敲回車

  你應該注意到了,在你敲下回車的時候,瀏覽器出現了loading效果,這意味着瀏覽器去重新加載了這個網頁

  看到這里,你應該發現了URL參數和hash參數的本質區別之一,URL參數的變更會引起瀏覽器重新加載網頁,而hash參數的變更則不會

 

  '#'在經過了一些年的發展之后,開始有了js事件支持。以IE為例,從IE8開始,IE支持onhashchange事件,每當瀏覽器檢測到地址欄中的hash值發生了變更,就會觸發一次onhashchange事件。通過這個事件,開發者可以開發出基於hash值變更的高級功能。

 

3.由'#'的特性而引申的新用法

   2008年,W3C提出了XHR的概念,通過使用XHR的api,人們發明出了ajax技術,使前端能夠實現頁面無刷新技術,即在頁面不刷新的情況下,更新頁面上的部分數據。例如,某個列表頁面帶有分頁,首次打開頁面時,js通過ajax加載並展示了第一頁的數據,當用戶點擊第二頁時,js再次發起請求加載得到第二頁的數據,然后把table中原來的數據清空,重新展示第二頁的數據,這樣實現了整個頁面不需要重新加載即可翻頁動態加載瀏覽數據。

 

  前端頁面無刷新技術的出現,是前端發展的一個歷史性的進步,在后來的幾年時間里,頁面無刷新技術開始瘋狂盛行,時至今日,該技術毫無疑問已經成為了前端技術的基石之一。而在前一小節我們講到,hash參數的變更不會引起頁面重新加載,這豈不是正好迎合了前端無刷新技術的思想么?於是'#'就自然而然地開始被大家應用到了各種頁面無刷新場景。

 

  人們發現,跟在'#'后面的內容不一定非得是一個元素的id,它可以是任何字符串,我們可以在'#'后面添加任意想要的字符串,以用來記錄想要存儲的信息,比如當前頁碼等。

 

  還是以表格分頁為例,我們可以人為地規定,"#page=1"表示查看第1頁的數據,"#page=5"表示查看第5頁的數據,以此類推。首次打開頁面時,我們先看url中有沒有hash參數,有則加載指定頁的數據,沒有則加載第1頁的數據。當我們點擊分頁上的第5頁時,我們用js把hash修改成"#page=5"。同時,我們事先定義好onhashchange事件,每當發現hash中的page改變了,我們就使用ajax去加載重新渲染新的頁的數據。這樣做的好處是,A用戶在逛網站,如果他逛到了第5頁,發現一個有趣的東西,想要分享給B用戶時,A用戶可以直接復制當前URL地址,比如"www.xxx.com/list#page=5",而B用戶打開該地址時,就能夠直接看到第5頁的數據。

 

  通過上面的例子我們可以看到,通過使用hash參數,我們可以給頁面任意增加想要的參數信息,參數的格式完全由我們自己定義,並且這些參數信息可以在頁面無刷新的情況下動態變更;同時,將攜帶了hash參數信息的地址分享給其他用戶時,其他用戶也可以得到這些頁面參數信息,以使分享者和被分享者看到的頁面狀態一致。這便是'#'在頁面無刷新技術出現后,引申出來的新用法

 

4.更多現代框架把'#'玩出了新花樣

  近十年來,前端開始出現了各種新式的MVC、MVM、MVVM框架,他們的出現為前端開發的設計思想做出了巨大貢獻,與此同時,這些框架也利用hash參數實現了自己的框架功能,也算是把hash給玩出了新花樣

 

  以Vue為例,Vue在構建單頁面應用SPA時,使用了虛擬路由功能來模擬頁面切換,而虛擬路由功能則正是利用了hash來實現的。我們先來看看Vue路由中幾個典型的URL示例:

  http://www.xxx.com/#/

  http://www.xxx.com/#/page

  http://www.xxx.com/#/page?a=1&b=2

 

  上面第一個示例表示虛擬路由中的根目錄,第二個示例表示虛擬路由中的某個頁面,第三個示例表示某個頁面帶有參數,請注意,第三個示例中的"?a=1&b=2"都是在'#'的后面,他們並不是真正的URL參數,而是hash參數中的一部分,只是格式跟標准URL參數一致而已,他們是虛擬的URL參數

  可以看到,Vue把整個hash參數都用來模擬URL路徑了,包括原始的URL參數也都一起模擬了。利用hash的頁面無刷新特性和onhashchange事件,Vue實現了動態路由切換展示不同頁面的效果。

 

5.結語

  '?'為URL參數,'#'為hash參數,前者很簡單沒什么花頭,而后者由於本身的特性,被廣大開發者和框架玩出了各種花樣。通過前面的詳細介紹,想必此刻的您已經對他們有了比較深入的了解。

  現在回到本文的最開頭,看看那些問題你都能自信地回答上來沒^_^

  最后的最后,再給你提一個問題,'?'和'#'哪個優先級高?可以自己動手測試下哦^_^


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM