URI片段

URI片段在電腦超文本中是指從屬於主資源的子資源的標識字符串。主資源由統一資源標識符（URI）標識，片段標識符指向從屬資源。

由井號`#`引入的片段標識符是文檔的URL的可選最後部分。通常用於標識該文檔的一部分。在RFC 3986中指定了其通用語法。URI中的井號`#`分隔符不是片段標識符的一部分。

## 概述

在URI中，井號`#`在URL末尾附近引入可選片段。RFC 3986定義的URI通用語法還允許使用問號`?`引入可選的查詢部分。在帶有查詢和片段的URI中，片段位於查詢之後。查詢部分取決於URI方案並由伺服器評估，例如，`http:`支持與`ftp:`不同的查詢。片段取決於文檔MIME類型並由客戶端（Web 瀏覽器）評估。客戶端在獲取文檔時不應將URI片段發送到伺服器，並且如果沒有本地應用程式的幫助，片段不會參與HTTP重定向。

以井號`#`結尾的URI是通用語法允許的，並且這是一種空片段。在MIME文檔類型（例如`text/html`或任何XML類型）中，不允許使用空標識符來匹配此語法上合法的構造。Web瀏覽器通常會在文檔頂部顯示一個空片段。

片段標識符的功能與URI的其餘部分不同：它的處理完全是客戶端進行的，沒有Web伺服器的參與，儘管伺服器通常幫助確定MIME類型，並且MIME類型決定片段的處理。當代理（例如Web瀏覽器）從Web伺服器請求Web資源時，代理將URI發送到伺服器，但不發送片段。相反，代理等待伺服器發送資源，然後代理根據文檔類型和片段值處理資源。

在HTML網頁中，代理將查找由HTML標記標識的錨點，該標記包含等於片段標識符的`id=`或`name=`屬性。

## 例子

- 在MIME為`text/html`頁面的URI（例如`http://www.example.org/foo.html#bar`）中，片段引用`id="bar"`的元素。
- 圖形Web瀏覽器通常滾動到位置頁面，以便由片段id標識的元素的頂部與視口（viewport）的頂部對齊；因此片段標識符經常用在目錄和永久連結中。
- 可以通過CSS偽類`:target`更改被標識的元素的外觀；維基百科使用它來高亮顯示所選的參考文獻。值得注意的是，CSS的`display:&nbsp;block`僅當內容是目標時才可用於顯示內容，否則通過`display:&nbsp;none`隱藏。
- 已棄用的`name`屬性（僅允許某些元素）在現已過時的瀏覽器中具有類似的用途。如果存在`name`，則必須和`id`相同。
- 在所有XML文檔類型中，包括對應於`xml:id`或類似`id`屬性的XHTML片段，都遵循`Name`語法並以字母、下劃線或冒號開頭。值得注意的是，它們不能以數字或連字符開頭。
- `xml:id`是少數通用XML屬性之一，例如`xml:lang`，無需顯式聲明命名空間即可使用。在XHTML中必須使用`id`，因為 XHTML 是在`xml:id`存在之前指定的。
- 在XML應用中，某種語法中的片段標識符可以是XPointer；例如，URI `http://www.example.org/foo.xml#xpointer(//Rube)` 中的片段標識符指的是由URI http://www.example.org/foo.xml標識的文檔中名為「Rube」的所有XML元素。給定該URI，XPointer處理器將獲取文檔的表示（例如通過從Internet請求）並返回文檔的「Rube」元素的表示。
- 在RDF詞彙表中，例如RDFS、OWL或SKOS，片段標識符用於標識同一XML命名空間中的資源，但不一定對應於文檔的特定部分。例如，`http://www.w3.org/2004/02/skos/core#broader`標識了SKOS Core詞彙中的「broader」概念，但它並不指代`http://www.w3.org/2004/02/skos/core`標識的資源的特定部分。它是一個完整的 RDF 文件，其中聲明了該特定概念的語義以及同一詞彙表中的其他概念。
- 在 MIME `text/plain`文檔的URI中，RFC 5147 使用關鍵字「`char`」和「`line`」指定文檔內字符和行位置和範圍的片段標識符。瀏覽器支持似乎缺乏。以下示例標識文本文檔的第 11 行到第 20 行：
- `http://example.com/document.txt#line=10,20`
- 在 MIME `text/csv` 文檔的 URI 中，RFC 7111 使用關鍵字"`row`" , "`col`", "`cell`"指定片段標識符作為行、列和單元格的選擇器，例如：
- `http://example.com/data.csv#row=4` –選擇第4行.
- `http://example.com/data.csv#col=2` – 選擇第二列.
- `http://example.com/data.csv#row=5-7` – 選擇從第5行開始的三個連續行.
- `http://example.com/data.csv#row=5-*` – 選擇從第5行開始的所有行.
- `http://example.com/data.csv#cell=4,1-6,2` – 選擇從第4行第1列開始到第6行第2列結束的區域.
- 在MIME audio/*、image/*、video/* 文檔的 URI 中，很少有定義片段或片段語義。媒體片段 URI 1.0（基本）語法支持使用關鍵字`t`和`xywh`沿二維（時間和空間）尋址媒體資源。因此，可以在音訊或影片 HTML5 元素的`src`屬性中使用以下媒體片段 URI：
- `http://example.com/foo.mp4#t=10,20`
- `http://example.com/bar.webm#t=40,80&xywh=160,120,320,240`
- 其他網站使用片段部分將一些額外資訊傳遞給在其上運行的腳本 - 例如，Google Video理解`#01h25m30s`格式的永久連結以在指定位置開始播放，而YouTube使用類似的代碼，例如`#t=3m25s`.
- 在JavaScript中，當前HTML或XHTML頁面的片段標識符可以在「hash」屬性`location.hash`中訪問 - 請注意，JavaScript 也可以與其他文檔類型一起使用。隨著AJAX的興起，一些網站使用片段標識符來模擬瀏覽器的後退按鈕行為，以進行不需要重新加載的頁面更改，或模擬子頁面。
- 例如，Gmail幾乎每個界面都使用單個URL – 郵箱、個人郵件、搜索結果、設置 – 該片段用於使這些界面可以直接連結。
- Adobe Flash網站可以使用片段部分來通知使用者網站或Web應用程式的狀態，並促進深度連結，通常在SWFAddress JavaScript庫的幫助下。
- 連結到JSON文檔的URI可以指定指向特定值的指針。
- 例如，以`#/foo`結尾的URL可用於從以`{ "foo": ["bar", "baz"], ... }`開頭的文檔中的「鍵-值對」中提取值。
- 在 MIME `application/pdf` 文檔的 URI 中，PDF查看器可識別許多片段標識符。例如，以 `.pdf#page=35`結尾的 URL 將導致大多數讀者打開 PDF 並滾動到第35頁。其他幾個參數也是可能的，包括`#nameddest=`（類似於HTML錨點）、`#search="word1 word2"`, `#zoom=`等。多個參數可以用 & 符號組合：
- `http://example.org/doc.pdf#view=fitb&nameddest=Chapter3`.
- 在SVG中，片段可以指定`viewBox()`, `preserveAspectRatio()`, `transform()`等參數。

## W3C提案

對於與純文本文檔（無法存儲錨元數據）一起使用的片段標識符，或者引用 HTML 文檔中作者未使用錨標記的位置，已經提出了一些W3C提案：

- 2012年9月，Media Fragments URI 1.0 (basic)已成為W3C推薦標準。
- Chrome版本80及更高版本實現了 WICG Text Fragments,因此`#:~:text=foo`將導致瀏覽器搜索`foo`，突出顯示匹配的文本，然後滾動到它。除了開始和結束之外，代碼片段還可以指定上下文：必須在`foo`之前或之後但不會突出顯示的文本（例如搜索前面帶有「night」的「vision」）。
- Python的Package Index將文件的MD5哈希值附加到URL作為片段標識符。如果MD5未被破壞，這可以用來確保包的完整性。
- `https://pypi.python.org ... zodbbrowser-0.3.1.tar.gz#md5=38dc89f294b24691d3f0d893ed3c119c`
- hash-bang片段是以感嘆號`!`開頭的片段。它用於索引動態單頁應用程式的現已被棄用的方法中。感嘆號在HTML4、XHTML和XML標識符中是非法的，因此與該功能有一定程度的分離。然而，它在HTML5中是允許的。
- 2009年至2015年間，Google網站管理員提出並推薦了一種「AJAX 抓取方案」，在有狀態AJAX頁面的片段標識符中使用初始感嘆號： `http://example.com/page?query#!state`
- 另一個實現是替換`#!`為`?_escaped_fragment_=`
- Hash-bang URI 被W3C的Jeni Tennison等許多人認為是有問題的，因為它們使那些沒有在瀏覽器中激活JavaScript的人無法訪問頁面。它們還會破壞HTTP Referer標頭，因為瀏覽器不允許發送Referer標頭中的片段標識符。
- 2015 年，Google 棄用了他們的hash-bang AJAX抓取提案，轉而建議使用漸進增強和HTML5的`history.pushState()`方法。
- Mozilla基金會Gervase Markham提出了一種用於搜索的片段標識符，其形式為`#!s!search terms`。在s(`#!s10!`) 後添加數字表示瀏覽器應搜索第n次出現的搜索詞。負數(`#!s-3!`)從文檔末尾開始向後搜索。Greasemonkey腳本可用於將此功能添加到兼容瀏覽器。
- `http://example.com/index.html#!s3!search terms`
- 蘇黎世聯邦理工學院的Erik Wilde和Marcel Baschnagel將其擴展為使用正則表達式（使用關鍵字「`match`」）來識別純文本文檔中的片段。他們還描述了一個原型實現作為Firefox瀏覽器的擴展。例如，以下命令將在文檔中的任何位置查找不區分大小寫的文本「RFC」：
- `http://example.com/document.txt#match=[rR][fF][cC]`
- 前瞻學會的K. Yee提出了用冒號和關鍵字分隔的「擴展片段標識符」，以將它們與錨標識符區分開來。具有「片段規範方案」id「`words`」的文本搜索片段標識符是該方案中的第一個提案。以下示例將在文檔中搜索字串「some context for a search term」的第一次出現，然後突出顯示單詞「search term」：
- `http://example.com/index.html#:words:some-context-for-a-(search-term)`
- 上述方案在Chrome 80版本中實現。
- LiveURLs項目提出了一種片段標識符格式，用於引用頁面內的文本區域，其形式為`#FWS+C`，其中 F 是第一個單詞的長度（最多5個字符），W是第一個單詞本身，S是所選文本的長度，C是所選文本的32位CRC。他們使用`#LFWS+C`的形式實現了該方案的變體作為 Firefox 瀏覽器的擴展，其中L是片段本身的長度，採用兩個十六進位數字。使用已實現的變體連結到單詞「Fragment」將產生：
- `http://example.com/index.html#115Fragm8+-52f89c4c`
- 在 Firefox 5 之前，Firefox 支持 XPath 連結，例如 #xpath:/html/body/div3，它可以與書籤結合使用，例如 http://antimatter15.com/wp/2009/11/xpath- bookmark-bookmarklet/ 用於連結缺少正確 ID 的 HTML 文檔。此功能已作為 https://bugzilla.mozilla.org/show_bug.cgi?id=457102 中代碼清理的一部分被刪除
- 在EPUB電子書格式中，EPUB Canonical Fragment Identifier （epubcfi，2011-2017）定義了一種W3C/International Digital Publishing Forum標準化方法，用於使用片段標識符引用任意內容，通過文檔結構和模式匹配來定位非錨定文本範圍。這些動態深層連結有助於在文本更新和使用後定位內容，例如在Apple Books中。

## 外部連結

- W3C Media Fragments Working Group, establishing a URI syntax and semantics to address media fragments in audiovisual material (such as a region in an image or a sub-clip of a video)
- MediaMixer Community Portal collects presentations, tutorials, use cases and demonstrators related to use of Media Fragment technology