Đoạn văn bản cho phép bạn chỉ định một đoạn văn bản trong phân mảnh của URL. Khi chuyển đến một URL có đoạn văn bản như vậy, trình duyệt có thể nhấn mạnh và thu hút sự chú ý của người dùng.
Giá trị nhận dạng mảnh
Chrome 80 là một bản phát hành lớn. Phiên bản này có một số tính năng được nhiều người mong đợi như Mô-đun ECMAScript trong Trình chạy web, phép gán rỗng, chuỗi tuỳ chọn, v.v. Như thường lệ, bản phát hành này được thông báo qua một bài đăng trên blog của Chromium. Bạn có thể xem một đoạn trích của bài đăng trên blog trong ảnh chụp màn hình sau đây.
id.Có thể bạn đang tự hỏi ý nghĩa của tất cả các hộp màu đỏ. Đây là kết quả của việc chạy đoạn mã sau trong Công cụ cho nhà phát triển. Thao tác này sẽ làm nổi bật tất cả các phần tử có thuộc tính id.
document.querySelectorAll('[id]').forEach((el) => {
el.style.border = 'solid 2px red';
});
Tôi có thể đặt một đường liên kết sâu đến bất kỳ phần tử nào được đánh dấu bằng hộp màu đỏ nhờ vào mã nhận dạng mảnh mà sau đó tôi sử dụng trong băm của URL trang. Giả sử tôi muốn liên kết sâu đến hộp Gửi ý kiến phản hồi cho chúng tôi trong Diễn đàn sản phẩm ở bên cạnh, tôi có thể làm như vậy bằng cách tạo URL https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1 theo cách thủ công.
Như bạn có thể thấy trong bảng điều khiển Elements (Phần tử) của Công cụ cho nhà phát triển, phần tử được đề cập có thuộc tính id với giá trị HTML1.
id của một phần tử.Nếu tôi phân tích cú pháp URL này bằng hàm khởi tạo URL() của JavaScript, thì các thành phần khác nhau sẽ được hiển thị.
Hãy lưu ý thuộc tính hash có giá trị #HTML1.
new URL('https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1');
/* Creates a new `URL` object
URL {
hash: "#HTML1"
host: "blog.chromium.org"
hostname: "blog.chromium.org"
href: "https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1"
origin: "https://blog.chromium.org"
password: ""
pathname: "/2019/12/chrome-80-content-indexing-es-modules.html"
port: ""
protocol: "https:"
search: ""
searchParams: URLSearchParams {}
username: ""
}
*/
Tuy nhiên, việc tôi phải mở Công cụ cho nhà phát triển để tìm id của một phần tử cho thấy khả năng cao là tác giả của bài đăng trên blog không có ý định liên kết đến phần cụ thể này của trang.
Nếu tôi muốn liên kết đến một nội dung không có id thì sao? Giả sử tôi muốn liên kết đến tiêu đề Mô-đun ECMAScript trong Web Worker. Như bạn có thể thấy trong ảnh chụp màn hình sau, <h1> được đề cập không có thuộc tính id, nghĩa là tôi không thể liên kết đến tiêu đề này. Đây là vấn đề mà
Đoạn văn bản giải quyết.
id.Đoạn văn bản
Đề xuất Đoạn văn bản bổ sung tính năng hỗ trợ cho việc chỉ định một đoạn văn bản trong hàm băm URL. Khi chuyển đến một URL có đoạn văn bản như vậy, tác nhân người dùng có thể nhấn mạnh và thu hút sự chú ý của người dùng.
Khả năng tương thích với trình duyệt
Vì lý do bảo mật, tính năng này yêu cầu mở các đường liên kết trong bối cảnh noopener.
Do đó, hãy nhớ thêm rel="noopener" vào mã đánh dấu liên kết <a> hoặc thêm noopener vào danh sách tính năng của cửa sổ Window.open().
start
Ở dạng đơn giản nhất, cú pháp của Đoạn văn bản như sau: Ký hiệu băm # theo sau là :~:text= và cuối cùng là start, đại diện cho văn bản được mã hoá theo phần trăm mà tôi muốn liên kết đến.
#:~:text=start
Ví dụ: giả sử tôi muốn liên kết đến tiêu đề Mô-đun ECMAScript trong Web Workers trong bài đăng trên blog thông báo về các tính năng trong Chrome 80, thì URL trong trường hợp này sẽ là:
Đoạn văn bản được nhấn mạnh như thế này. Nếu bạn nhấp vào đường liên kết trong một trình duyệt hỗ trợ như Chrome, thì đoạn văn bản sẽ được làm nổi bật và cuộn vào khung hiển thị:
start và end
Bây giờ, nếu tôi muốn liên kết đến toàn bộ phần có tiêu đề Mô-đun ECMAScript trong Web Workers, chứ không chỉ tiêu đề của phần đó thì sao? Việc mã hoá phần trăm toàn bộ văn bản của phần này sẽ khiến URL thu được dài đến mức không thể sử dụng được.
May mắn là có một cách hay hơn. Thay vì toàn bộ văn bản, tôi có thể đóng khung một phần cụ thể của văn bản bằng cú pháp start,end. Tôi chỉ định một vài từ được mã hoá theo phần trăm ở đầu đoạn văn bản và một vài từ được mã hoá theo phần trăm ở cuối đoạn văn bản, phân tách bằng dấu phẩy.
Mã này có dạng như sau:
Đối với start, tôi có ECMAScript%20Modules%20in%20Web%20Workers, sau đó là dấu phẩy, tiếp theo là ES%20Modules%20in%20Web%20Workers. dưới dạng end. Khi bạn nhấp vào một trình duyệt hỗ trợ như Chrome, toàn bộ phần này sẽ được làm nổi bật và cuộn vào khung hiển thị:
Bây giờ, bạn có thể thắc mắc về lựa chọn start và end của tôi. Trên thực tế, URL ngắn hơn một chút
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules,Web%20Workers.
chỉ có hai từ ở mỗi bên cũng sẽ hoạt động. So sánh start và end với các giá trị trước đó.
Nếu tôi tiến thêm một bước và giờ chỉ sử dụng một từ cho cả start và end, bạn có thể thấy rằng tôi đang gặp rắc rối. URL
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript,Workers.
hiện thậm chí còn ngắn hơn, nhưng đoạn văn bản được đánh dấu không còn là đoạn văn bản được chọn ban đầu nữa. Phần đánh dấu dừng lại ở lần xuất hiện đầu tiên của từ Workers., điều này là chính xác, nhưng không phải là điều tôi muốn đánh dấu. Vấn đề là phần đã chọn không được xác định duy nhất bằng các giá trị start và end một từ hiện tại:
prefix- và -suffix
Sử dụng các giá trị đủ dài cho start và end là một giải pháp để có được đường liên kết riêng biệt.
Tuy nhiên, trong một số trường hợp, điều này là không thể. Ngoài ra, tại sao tôi lại chọn bài đăng trên blog về bản phát hành Chrome 80 làm ví dụ? Câu trả lời là trong bản phát hành này,
Đoạn văn bản đã được giới thiệu:
Hãy lưu ý rằng trong ảnh chụp màn hình ở trên, từ "text" (văn bản) xuất hiện 4 lần. Lần xuất hiện thứ tư được viết bằng phông chữ mã màu xanh lục. Nếu muốn liên kết đến từ cụ thể này, tôi sẽ đặt start thành text. Vì từ "text" chỉ có một từ nên không thể có end. Chúng tôi nên làm gì? URL
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=text
khớp với lần xuất hiện đầu tiên của từ "Text" đã có trong tiêu đề:
May mắn là có một giải pháp. Trong những trường hợp như vậy, tôi có thể chỉ định prefix- và -suffix. Từ trước phông chữ mã màu xanh lục "text" là "the" và từ sau là "parameter". Không có từ nào trong số ba lần xuất hiện khác của từ "văn bản" có cùng các từ xung quanh. Khi đã biết thông tin này, tôi có thể điều chỉnh URL trước đó và thêm prefix- và -suffix. Giống như các tham số khác, các tham số này cũng cần được mã hoá theo phần trăm và có thể chứa nhiều từ.
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=the-,text,-parameter.
Để cho phép trình phân tích cú pháp xác định rõ ràng prefix- và -suffix, bạn cần tách các giá trị này khỏi start và end (không bắt buộc) bằng dấu gạch ngang -.
Cú pháp đầy đủ
Sau đây là cú pháp đầy đủ của Đoạn văn bản. (Dấu ngoặc vuông cho biết tham số không bắt buộc.)
Giá trị của tất cả tham số cần được mã hoá phần trăm. Điều này đặc biệt quan trọng đối với các ký tự dấu gạch ngang -, dấu và & và dấu phẩy ,, để chúng không được diễn giải là một phần của cú pháp lệnh văn bản.
#:~:text=[prefix-,]start[,end][,-suffix]
Mỗi prefix-, start, end và -suffix chỉ có thể khớp với văn bản trong một phần tử cấp khối, nhưng toàn bộ dải ô start,end có thể trải dài trên nhiều khối. Ví dụ: :~:text=The quick,lazy dog không khớp trong ví dụ sau, vì chuỗi bắt đầu "The quick" không xuất hiện trong một phần tử cấp khối duy nhất, không bị gián đoạn:
<div>
The
<div></div>
quick brown fox
</div>
<div>jumped over the lazy dog</div>
Tuy nhiên, biểu thức này khớp trong ví dụ sau:
<div>The quick brown fox</div>
<div>jumped over the lazy dog</div>
Tạo URL đoạn văn bản bằng tiện ích của trình duyệt
Việc tạo URL của Đoạn văn bản theo cách thủ công rất tẻ nhạt, đặc biệt là khi phải đảm bảo rằng các URL đó là duy nhất. Nếu bạn thực sự muốn, thông số kỹ thuật có một số mẹo và liệt kê chính xác các bước để tạo URL Đoạn văn bản. Chúng tôi cung cấp một tiện ích trình duyệt nguồn mở có tên là Đường liên kết đến Đoạn văn bản cho phép bạn liên kết đến bất kỳ văn bản nào bằng cách chọn văn bản đó, sau đó nhấp vào "Sao chép đường liên kết đến văn bản đã chọn" trong trình đơn theo bối cảnh. Tiện ích này có trên các trình duyệt sau:
- Liên kết đến đoạn văn bản cho Google Chrome
- Đường liên kết đến đoạn văn bản cho Microsoft Edge
- Liên kết đến đoạn văn bản cho Mozilla Firefox
- Đường liên kết đến đoạn văn bản cho Apple Safari
Nhiều đoạn văn bản trong một URL
Xin lưu ý rằng nhiều đoạn văn bản có thể xuất hiện trong một URL. Các đoạn văn bản cụ thể cần được phân tách bằng ký tự dấu và &. Sau đây là ví dụ về một đường liên kết có 3 đoạn văn bản:
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=Text%20URL%20Fragments&text=text,-parameter&text=:~:text=On%20islands,%20birds%20can%20contribute%20as%20much%20as%2060%25%20of%20a%20cat's%20diet.
Kết hợp các đoạn văn bản và phần tử
Bạn có thể kết hợp đoạn văn bản với đoạn phần tử truyền thống. Bạn hoàn toàn có thể sử dụng cả hai trong cùng một URL, chẳng hạn như để cung cấp một phương án dự phòng có ý nghĩa trong trường hợp văn bản gốc trên trang thay đổi, khiến đoạn văn bản không còn khớp nữa. URL
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1:~:text=Give%20us%20feedback%20in%20our%20Product%20Forums.
liên kết đến phần Gửi ý kiến phản hồi cho chúng tôi trong
Diễn đàn sản phẩm
chứa cả một mảnh phần tử (HTML1) và một mảnh văn bản
(text=Give%20us%20feedback%20in%20our%20Product%20Forums.):
Lệnh phân mảnh
Có một thành phần của cú pháp mà tôi chưa giải thích: lệnh phân mảnh :~:. Để tránh các vấn đề về khả năng tương thích với các mảnh phần tử URL hiện có như minh hoạ, quy cách của Đoạn văn bản sẽ giới thiệu lệnh mảnh. Lệnh phân mảnh là một phần của phân mảnh của URL được phân tách bằng chuỗi mã :~:. Phần này được dành riêng cho các hướng dẫn về tác nhân người dùng, chẳng hạn như text=, và bị loại bỏ khỏi URL trong quá trình tải để tập lệnh của tác giả không thể tương tác trực tiếp với phần này. Hướng dẫn về tác nhân người dùng cũng được gọi là lệnh. Do đó, trong trường hợp cụ thể, text= được gọi là lệnh văn bản.
Phát hiện tính năng
Để phát hiện khả năng hỗ trợ, hãy kiểm tra thuộc tính fragmentDirective chỉ có thể đọc trên document. Chỉ thị mảnh là một cơ chế để URL chỉ định các lệnh hướng đến trình duyệt thay vì tài liệu. Mục đích là để tránh tương tác trực tiếp với tập lệnh của tác giả, nhờ đó, bạn có thể thêm các hướng dẫn về tác nhân người dùng trong tương lai mà không lo gây ra thay đổi có thể gây lỗi cho nội dung hiện có. Một ví dụ tiềm năng về những nội dung bổ sung trong tương lai có thể là gợi ý dịch.
if ('fragmentDirective' in document) {
// Text Fragments is supported.
}
Tính năng phát hiện chủ yếu dành cho các trường hợp đường liên kết được tạo động (ví dụ: bằng công cụ tìm kiếm) để tránh phân phát đường liên kết đến đoạn văn bản cho các trình duyệt không hỗ trợ.
Tạo kiểu cho các đoạn văn bản
Theo mặc định, các trình duyệt sẽ tạo kiểu cho các đoạn văn bản giống như cách chúng tạo kiểu cho mark (thường là màu đen trên nền vàng, màu hệ thống CSS cho mark). Biểu định kiểu tác nhân người dùng chứa CSS có dạng như sau:
:root::target-text {
color: MarkText;
background: Mark;
}
Như bạn có thể thấy, trình duyệt hiển thị một bộ chọn giả
::target-text mà bạn có thể dùng để
tuỳ chỉnh phần đánh dấu được áp dụng. Ví dụ: bạn có thể thiết kế các đoạn văn bản có chữ màu đen trên nền đỏ. Như thường lệ, hãy nhớ
kiểm tra độ tương phản màu
để kiểu ghi đè không gây ra vấn đề về khả năng hỗ trợ tiếp cận và đảm bảo phần đánh dấu thực sự
nổi bật so với phần còn lại của nội dung.
:root::target-text {
color: black;
background-color: red;
}
Polyfill
Tính năng Đoạn văn bản có thể được polyfill ở một mức độ nào đó. Chúng tôi cung cấp một polyfill (được tiện ích sử dụng nội bộ) cho các trình duyệt không hỗ trợ sẵn Đoạn văn bản, trong đó chức năng này được triển khai bằng JavaScript.
Tạo đường liên kết đến đoạn văn bản có lập trình
Polyfill chứa một tệp fragment-generation-utils.js mà bạn có thể nhập và sử dụng để tạo đường liên kết đến Đoạn văn bản. Điều này được trình bày trong mã mẫu:
const { generateFragment } = await import('https://unpkg.com/text-fragments-polyfill/dist/fragment-generation-utils.js');
const result = generateFragment(window.getSelection());
if (result.status === 0) {
let url = `${location.origin}${location.pathname}${location.search}`;
const fragment = result.fragment;
const prefix = fragment.prefix ?
`${encodeURIComponent(fragment.prefix)}-,` :
'';
const suffix = fragment.suffix ?
`,-${encodeURIComponent(fragment.suffix)}` :
'';
const start = encodeURIComponent(fragment.textStart);
const end = fragment.textEnd ?
`,${encodeURIComponent(fragment.textEnd)}` :
'';
url += `#:~:text=${prefix}${start}${end}${suffix}`;
console.log(url);
}
Lấy Đoạn văn bản cho mục đích phân tích
Nhiều trang web sử dụng mảnh để định tuyến, đó là lý do trình duyệt loại bỏ Mảnh văn bản để không làm hỏng các trang đó. Có một nhu cầu đã được ghi nhận về việc hiển thị các đường liên kết đến Đoạn văn bản trên các trang, chẳng hạn như cho mục đích phân tích, nhưng giải pháp đề xuất vẫn chưa được triển khai. Để giải quyết vấn đề này, bạn có thể sử dụng mã sau để trích xuất thông tin.
new URL(performance.getEntries().find(({ type }) => type === 'navigate').name).hash;
Bảo mật
Các lệnh của đoạn văn bản chỉ được gọi khi người dùng thực hiện thao tác điều hướng đầy đủ (không phải trên cùng một trang)
do
hoạt động của người dùng.
Ngoài ra, các thao tác điều hướng bắt nguồn từ một nguồn gốc khác với đích đến yêu cầu thao tác điều hướng phải diễn ra trong bối cảnh noopener, sao cho trang đích được biết là đã tách biệt đủ. Các lệnh về đoạn văn bản chỉ được áp dụng cho khung chính. Điều này có nghĩa là văn bản không được tìm kiếm bên trong iframe và thao tác điều hướng iframe không gọi đoạn văn bản.
Quyền riêng tư
Điều quan trọng là việc triển khai thông số kỹ thuật của Đoạn văn bản không làm rò rỉ thông tin về việc có tìm thấy đoạn văn bản trên một trang hay không. Mặc dù các đoạn phần tử hoàn toàn nằm trong tầm kiểm soát của tác giả trang gốc, nhưng bất kỳ ai cũng có thể tạo đoạn văn bản. Bạn có nhớ trong ví dụ của tôi, không có cách nào để liên kết đến tiêu đề Mô-đun ECMAScript trong Web Workers vì <h1> không có id, nhưng bất kỳ ai, kể cả tôi, đều có thể liên kết đến bất kỳ đâu bằng cách tạo đoạn văn bản một cách cẩn thận không?
Giả sử tôi điều hành một mạng quảng cáo độc hại evil-ads.example.com. Hãy tưởng tượng thêm rằng trong một trong các iframe quảng cáo của tôi, tôi đã tạo động một iframe ẩn trên nhiều nguồn gốc cho dating.example.com bằng URL đoạn văn bản dating.example.com#:~:text=Log%20Out sau khi người dùng tương tác với quảng cáo. Nếu tìm thấy văn bản "Đăng xuất", tôi biết nạn nhân đã đăng nhập vào dating.example.com, nhờ đó tôi có thể lập hồ sơ người dùng. Vì việc triển khai Đoạn văn bản đơn giản có thể quyết định rằng một kết quả trùng khớp thành công sẽ gây ra chuyển đổi tiêu điểm, nên trên evil-ads.example.com, tôi có thể theo dõi sự kiện blur và do đó biết được thời điểm xảy ra kết quả trùng khớp. Trong
Chrome, chúng tôi đã triển khai Đoạn văn bản theo cách không thể xảy ra trường hợp như vậy.
Một cuộc tấn công khác có thể là khai thác lưu lượng truy cập mạng dựa trên vị trí cuộn. Giả sử tôi có quyền truy cập vào nhật ký lưu lượng truy cập mạng của nạn nhân, chẳng hạn như quản trị viên của mạng nội bộ công ty. Bây giờ, hãy tưởng tượng có một tài liệu dài về nhân sự có tiêu đề Việc nên làm nếu bạn bị..., sau đó là danh sách các tình trạng như kiệt sức, lo âu, v.v. Tôi có thể đặt một pixel theo dõi bên cạnh mỗi mục trong danh sách. Nếu sau đó tôi xác định rằng việc tải tài liệu xảy ra đồng thời với việc tải pixel theo dõi bên cạnh, giả sử là mục kiệt sức, thì với tư cách là quản trị viên mạng nội bộ, tôi có thể xác định rằng một nhân viên đã nhấp vào một đường liên kết đến đoạn văn bản có :~:text=burn%20out mà nhân viên đó có thể cho rằng là bí mật và không ai nhìn thấy. Vì ví dụ này có phần gượng gạo ngay từ đầu và việc khai thác lỗ hổng này đòi hỏi phải đáp ứng các điều kiện tiên quyết rất cụ thể, nên nhóm bảo mật của Chrome đã đánh giá rủi ro của việc triển khai thao tác cuộn khi điều hướng là có thể kiểm soát được.
Các tác nhân người dùng khác có thể quyết định hiển thị một phần tử trên giao diện người dùng để cuộn theo cách thủ công.
Đối với những trang web muốn chọn không sử dụng, Chromium hỗ trợ giá trị tiêu đề Chính sách tài liệu mà họ có thể gửi để tác nhân người dùng không xử lý URL của Đoạn văn bản.
Document-Policy: force-load-at-top
Tắt đoạn văn bản
Cách dễ nhất để tắt tính năng này là sử dụng một tiện ích có thể chèn tiêu đề phản hồi HTTP, ví dụ: ModHeader (không phải là sản phẩm của Google), để chèn tiêu đề phản hồi (không phải yêu cầu) như sau:
Document-Policy: force-load-at-top
Một cách khác phức tạp hơn để chọn không sử dụng là dùng chế độ cài đặt dành cho doanh nghiệp
ScrollToTextFragmentEnabled.
Để thực hiện việc này trên macOS, hãy dán lệnh sau vào dòng lệnh.
defaults write com.google.Chrome ScrollToTextFragmentEnabled -bool false
Trên Windows, hãy làm theo tài liệu trên trang web hỗ trợ của Trợ giúp về Google Chrome Enterprise.
Đoạn văn bản trong kết quả tìm kiếm trên web
Đối với một số nội dung tìm kiếm, công cụ tìm kiếm Google sẽ cung cấp câu trả lời nhanh hoặc thông tin tóm tắt kèm theo một đoạn trích nội dung từ một trang web có liên quan. Những đoạn trích nổi bật này thường xuất hiện khi cụm từ tìm kiếm có dạng câu hỏi. Khi nhấp vào một đoạn trích nổi bật, người dùng sẽ được đưa thẳng đến văn bản của đoạn trích nổi bật đó trên trang web nguồn. Tính năng này hoạt động nhờ các URL Đoạn văn bản được tạo tự động.
Kết luận
URL của đoạn văn bản là một tính năng mạnh mẽ để liên kết đến văn bản tuỳ ý trên trang web. Cộng đồng học thuật có thể sử dụng miền này để cung cấp các đường liên kết trích dẫn hoặc tham khảo có độ chính xác cao. Công cụ tìm kiếm có thể sử dụng thuộc tính này để liên kết sâu đến kết quả văn bản trên các trang. Các trang mạng xã hội có thể sử dụng API này để cho phép người dùng chia sẻ các đoạn cụ thể của trang web thay vì ảnh chụp màn hình không truy cập được. Tôi hy vọng bạn bắt đầu sử dụng URL của đoạn văn bản và thấy chúng hữu ích như tôi. Hãy nhớ cài đặt tiện ích Đường liên kết đến đoạn văn bản của trình duyệt.
Đường liên kết có liên quan
- Bản nháp thông số kỹ thuật
- Đánh giá của TAG
- Mục Trạng thái Nền tảng Chrome
- Lỗi theo dõi của Chrome
- Chuỗi bài đăng về ý định phát hành
- Chuỗi WebKit-Dev
- Chuỗi bài viết về quan điểm của Mozilla đối với các tiêu chuẩn
Xác nhận
Đoạn văn bản được Nick Burris và David Bokan triển khai và chỉ định, với sự đóng góp của Grant Wang. Cảm ơn Joe Medley đã xem xét kỹ lưỡng tài liệu này.