URI's fragment

URI & URL

URI,Uniform Resource Identifier,統(tǒng)一資源標(biāo)識符。
URL,Uniform Resource Location,統(tǒng)一資源定位符。
URI 簡單來理解就是標(biāo)識/定義了一個資源,而 URL 在定義/標(biāo)識資源的同時還需要描述如何訪問到該資源??梢哉J(rèn)為 URL 是 URI 的一個子集。
舉個例子:
公司里每個人都有一個內(nèi)部唯一的花名,這個花名其實就可以認(rèn)為是 URI,它對應(yīng)了公司內(nèi)部唯一的一個人(資源)。當(dāng)我需要找這個人時,雖然我知道了花名(URI),但是并找不到他人,因為我不知道他的工位,這時候就需要知道他的工位號如 13B-11 ,工位號+花名其實就是一個 URL,它指定了一個人以及怎么找到這個人的位置。
上述例子可能并不規(guī)范,但是感覺這樣比較容易理解區(qū)分。一般來說 URI 有一個通用的結(jié)構(gòu)描述:
scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]

Example

其實現(xiàn)在我們不必刻意去區(qū)分 URI / URL / URN 。在 [RFC3986]上已經(jīng)明確說明這個點:

Future specifications and related documentation should
use the general term "URI" rather than the more restrictive terms
"URL" and "URN".

fragment

主要資源是由 URI 進行標(biāo)識,URI 中的 fragment 用來標(biāo)識次級資源。我理解看來,fragment 主要是用來標(biāo)識 URI 所標(biāo)識資源里的某個資源。
在 URI 的末尾通過 hash mark(#)作為 fragment 的開頭,其中 # 不屬于 fragment 的值。
https://domain/index#L18
這個 URI 中 L18 就是 fragment 的值。這有哪些特殊的地方呢?

  1. # 有別于 ?,? 后面的查詢字符串會被網(wǎng)絡(luò)請求帶上服務(wù)器,而 fragment 不會被發(fā)送的服務(wù)器;
  2. fragment 的改變不會觸發(fā)瀏覽器刷新頁面,但是會生成瀏覽歷史;
  3. fragment 會被瀏覽器根據(jù)文件媒體類型(MIME type)進行對應(yīng)的處理;
  4. Google 的搜索引擎會忽略 # 及其后面的字符串。

針對以上幾點特性,分別介紹下 URI fragment 的應(yīng)用。

特性 1 & 2 單頁面路由

針對 1、2 這兩個特性,目前主要的應(yīng)用就是單頁面路由。具體原理簡單描述如下:
JavaScript 提供了 location.hash 來操作當(dāng)前 URI 的 fragment,同時提供了 Hashchange 事件監(jiān)聽 fragment 的變化。利用這兩個 API 再結(jié)合上述特性 1、2 就可以實現(xiàn)一個簡單前端路由。具體流程如下圖:

Example

修改 location.hash 值,觸發(fā) hashchange 事件,JS 處理對應(yīng)的邏輯,改變頁面 UI 實現(xiàn)頁面的跳轉(zhuǎn),并在瀏覽器中產(chǎn)生歷史記錄。
具體代碼實現(xiàn)可以參考 vue-router hash 模式下的實現(xiàn) [https://github.com/vuejs/vue-router/blob/dev/src/history/hash.js]。
hashchange event 目前的兼容性表現(xiàn)較好,主流瀏覽器都支持【[caniuse]】。
實現(xiàn)單頁面路由還會使用 H5 為 history 新增的兩個 API History.pushState() & Histroy. replaceState ()。雖然在 URL 美觀度上很令人滿意,但是也存在缺點,如兼容性表現(xiàn)、對 Web 容器配置的額外要求 —— 直接使用 pushState 的 URL 訪問應(yīng)用,則會 404,需要 Web 容器對這些 URL 進行處理,重寫到對應(yīng)的 HTML 頁面上。
具體代碼實現(xiàn)可以參考 vue-router histroy 模式下的實現(xiàn) [https://github.com/vuejs/vue-router/blob/dev/src/history/html5.js]。

特性 3 HTML 錨點

在 HTML 中比較常見的一個應(yīng)用 —— 頁面內(nèi)定位。在頁面中通過設(shè)置標(biāo)簽的 id 屬性來定義錨點,從而實現(xiàn)錨點定位。實際上錨點定位的實現(xiàn)正是依賴了 fragment 的特性 3。如這個 URI https://domain/index.html#L18,假設(shè)返回的文件類型是 text/html,則瀏覽器會讀取 URI’s fragment,然后在頁面中尋找 L18 這個錨點,并將頁面滾動到該錨點的位置。
因此我們當(dāng)點擊 <a href="#top">top</a>時,實際上處理過程是 URI 的 hash 發(fā)生變化,然后瀏覽器讀取新的 fragment,并尋找 DOM 中是否存在對應(yīng)的錨點,將該錨點顯示到頁面中。
在 MIME Type 為 HTML 或 XML 時,如https://domain/index.html#這個 URI 中是空的 fragment,則瀏覽器默認(rèn)顯示頁面的最頂端。
URI 對應(yīng)的資源類型不同,瀏覽器對該 URI’s fragment 的處理方式就不一樣,具體不同類型的處理方式可以參閱:[https://en.wikipedia.org/wiki/Fragment_identifier#Examples]

特性 4

特性4 其實是針對 hash 模式前端路由來說的一個缺點。因為 fragment 會被 Google 搜索引擎忽略掉,因此對于用 hash 模式前端路由的應(yīng)用的 SEO 來說是很不友好的。不過 Google 給了一個方案,就是在 # 緊跟一個 ! ,這樣Google 搜索引擎就會將這個 URI 進行轉(zhuǎn)換,如 https://domain/index.html#!L18轉(zhuǎn)換后就成為了 https://domain/index.html?_escaped_fragment_=L18。這樣搜索引擎就會攜帶上 URI’s fragment 直接去訪問這個 URI,開發(fā)者可以利用這個 trick 優(yōu)化網(wǎng)站的 SEO。

小結(jié)

  1. fragment 對于 HTML 文檔來說就是頁面內(nèi)的定位標(biāo)識符,可以實現(xiàn) HTML 頁面內(nèi)的定位。當(dāng)然瀏覽器針對不同類型的資源會有區(qū)分的處理 fragment;
  2. 利用 fragment 實現(xiàn)前端頁面無刷新修改 Brower’s URI;
  3. 根據(jù)搜索引擎規(guī)則,可以優(yōu)化無刷新修改頁面的 SEO;
    對于 URI’s fragment 的探究也就到這里,附上下關(guān)的參考 Links:
  4. [http://www.ietf.org/rfc/rfc3986.txt]
  5. [https://en.wikipedia.org/wiki/Fragment_identifier]
  6. [http://www.ruanyifeng.com/blog/2011/03/url_hash.html]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,761評論 25 709
  • 一、概念(載錄于:http://www.cnblogs.com/EricaMIN1987_IT/p/3837436...
    yuantao123434閱讀 8,726評論 6 152
  • 今年的第一場雪來的悄無聲息,還沒睡醒,就聽室友嘰嘰喳喳地吵著,哇,下雪啦,天哪,好美哦。裹在暖暖被窩里的我不以為然...
    明月sw閱讀 245評論 0 0
  • GAI的音樂確實抓耳,之前第一次聽到,簡直,莫名其妙的戳耳,扎心,但老實說講不出是具體好在哪兒。把原來的翻出來一直...
    城南栗子閱讀 472評論 0 1

友情鏈接更多精彩內(nèi)容