URI's fragment

URI & URL

URI,Uniform Resource Identifier,统一资源标识符。
URL,Uniform Resource Location,统一资源定位符。

URI 简单来理解就是标识/定义了一个资源,而 URL 在定义/标识资源的同时还需要描述如何访问到该资源。可以认为 URL 是 URI 的一个子集。

举个例子:
        公司里每个人都有一个内部唯一的花名,这个花名其实就可以认为是 URI,它对应了公司内部唯一的一个人(资源)。当我需要找这个人时,虽然我知道了花名(URI),但是并找不到他人,因为我不知道他的工位,这时候就需要知道他的工位号如 13B-11 ,工位号+花名其实就是一个 URL,它指定了一个人以及怎么找到这个人的位置。
    
上述例子可能并不规范,但是感觉这样比较容易理解区分。一般来说 URI 有一个通用的结构描述:

scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]

auto-orient

其实现在我们不必刻意去区分 URI / URL / URN 。在 [RFC3986]上已经明确说明这个点:

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

 

fragment
    主要资源是由 URI 进行标识,URI 中的 fragment 用来标识次级资源。我理解看来,fragment 主要是用来标识 URI 所标识资源里的某个资源。
    在 URI 的末尾通过 hash mark(#)作为 fragment 的开头,其中 # 不属于 fragment 的值。

https://domain/index#L18

这个 URI 中 L18 就是 fragment 的值。这有哪些特殊的地方呢?

  1.     # 有别于 ?? 后面的查询字符串会被网络请求带上服务器,而 fragment 不会被发送的服务器;
  2.     fragment 的改变不会触发浏览器刷新页面,但是会生成浏览历史;
  3.     fragment 会被浏览器根据文件媒体类型(MIME type)进行对应的处理;
  4.     Google 的搜索引擎会忽略 # 及其后面的字符串。

 

针对以上几点特性,分别介绍下 URI fragment 的应用。


特性 1 & 2  单页面路由
    针对 1、2 这两个特性,目前主要的应用就是单页面路由。

具体原理简单描述如下:
    JavaScript 提供了 location.hash 来操作当前 URI 的 fragment,同时提供了 Hashchange 事件监听 fragment 的变化。利用这两个 API 再结合上述特性 1、2 就可以实现一个简单前端路由。具体流程如下图:auto-orient

    修改 location.hash 值,触发 hashchange 事件,JS 处理对应的逻辑,改变页面 UI 实现页面的跳转,并在浏览器中产生历史记录。具体代码实现可以参考 vue-router hash 模式下的实现  https://github.com/vuejs/vue-router/blob/dev/src/history/hash.js


hashchange event 目前的兼容性表现较好,主流浏览器都支持【[caniuse]】。
实现单页面路由还会使用 H5 为 history 新增的两个

API History.pushState() & Histroy. replaceState ()

虽然在 URL 美观度上很令人满意,但是也存在缺点,如兼容性表现、对 Web 容器配置的额外要求 —— 直接使用 pushState 的 URL 访问应用,则会 404,需要 Web 容器对这些 URL 进行处理,重写到对应的 HTML 页面上。具体代码实现可以参考 vue-router histroy 模式下的实现 https://github.com/vuejs/vue-router/blob/dev/src/history/html5.js

 

特性 3  HTML 锚点
    在 HTML 中比较常见的一个应用 —— 页面内定位。在页面中通过设置标签的 id 属性来定义锚点,从而实现锚点定位。实际上锚点定位的实现正是依赖了 fragment 的特性 3。如这个URI  https://domain/index.html#L18,假设返回的文件类型是 text/html,则浏览器会读取 URI’s fragment,然后在页面中寻找 L18 这个锚点,并将页面滚动到该锚点的位置。
    因此我们当点击 <a href="#top">top</a>时,实际上处理过程是 URI 的 hash 发生变化,然后浏览器读取新的 fragment,并寻找 DOM 中是否存在对应的锚点,将该锚点显示到页面中。
    在 MIME Type 为 HTML 或 XML 时,如 https://domain/index.html# 这个 URI 中是空的 fragment,则浏览器默认显示页面的最顶端。
URI 对应的资源类型不同,浏览器对该 URI’s fragment 的处理方式就不一样,具体不同类型的处理方式可以参阅:https://en.wikipedia.org/wiki/Fragment_identifier#Examples


特性 4
    特性4 其实是针对 hash 模式前端路由来说的一个缺点。因为 fragment 会被 Google 搜索引擎忽略掉,因此对于用 hash 模式前端路由的应用的 SEO 来说是很不友好的。不过 Google 给了一个方案,就是在 # 紧跟一个 ! ,这样Google 搜索引擎就会将这个 URI 进行转换,如 https://domain/index.html#!L18转换后就成为了 https://domain/index.html?_escaped_fragment_=L18。这样搜索引擎就会携带上 URI’s fragment 直接去访问这个 URI,开发者可以利用这个 trick 优化网站的 SEO。

 

小结

    fragment 对于 HTML 文档来说就是页面内的定位标识符,可以实现 HTML 页面内的定位。当然浏览器针对不同类型的资源会有区分的处理 fragment;
利用  fragment 实现前端页面无刷新修改 Brower’s URI;
    根据搜索引擎规则,可以优化无刷新修改页面的 SEO;


对于  URI’s fragment 的探究也就到这里,附上下关的参考 Links:

转载于:https://my.oschina.net/u/3901362/blog/3075684

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值