Link in grassetto dove nessuno ha mai aggiunto link prima: frammenti di testo

I frammenti di testo ti consentono di specificare uno snippet di testo nel frammento di URL. Quando si accede a un URL con questo frammento di testo, il browser può enfatizzare e/o portarla all'attenzione dell'utente.

Identificatori di frammenti

Chrome 80 è stata una grande novità. Conteneva una serie di funzionalità molto attese come Moduli ECMAScript nei web worker, coalescing nullo, concatenamento facoltativo e altro ancora. Il lancio è stato, come al solito, annunciate tramite un post del blog sulla Blog di Chromium. Puoi vedere un estratto del post del blog nello screenshot di seguito.

Post del blog di Chromium con riquadri rossi attorno a elementi con un attributo id.

Probabilmente ti starai chiedendo cosa significano tutte le caselle rosse. Sono il risultato dell'esecuzione successivo snippet in DevTools. Evidenzia tutti gli elementi che hanno un attributo id.

document.querySelectorAll('[id]').forEach((el) => {
  el.style.border = 'solid 2px red';
});

Posso inserire un link diretto a qualsiasi elemento evidenziato con una casella rossa grazie al identificatore di frammento che poi uso nell'hash della classe dell'URL della pagina. Supponendo di voler creare un link diretto alla sezione Forniscici feedback nel nostro Forum dei prodotti nella sezione a parte, potrei farlo creando a mano l'URL https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1. Come puoi vedere nel riquadro Elementi di Strumenti per sviluppatori, l'elemento in questione ha un id con il valore HTML1.

Strumenti per sviluppatori che mostrano il id di un elemento.

Se analizzo questo URL con il costruttore URL() di JavaScript, i diversi componenti vengono rivelati. Osserva la proprietà hash con il valore #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: ""
}
*/

Il fatto che sia necessario aprire Strumenti per sviluppatori per trovare il id di un elemento parla molto sulla probabilità che l'autore del link a questa particolare sezione della pagina nel post del blog.

Cosa devo fare se voglio creare un link a qualcosa senza id? Supponiamo di voler collegare i moduli ECMAScript nell'intestazione Web worker. Come puoi vedere nello screenshot di seguito, il <h1> in questione non hanno un attributo id, il che significa che non c'è modo di creare un link a questo titolo. Questo è il problema Frammenti di testo risolti.

Gli strumenti per sviluppatori mostrano un'intestazione senza id.

Frammenti di testo

La proposta Frammenti di testo aggiunge il supporto per specificando uno snippet di testo nell'hash dell'URL. Quando accedi a un URL con un frammento di testo di questo tipo, il parametro lo user agent può enfatizzare e/o portarlo all'attenzione dell'utente.

Compatibilità del browser

Supporto dei browser

  • Chrome: 89.
  • Edge: 89.
  • Firefox: non supportato.
  • Safari: non supportato.

Origine

Per motivi di sicurezza, la funzione richiede l'apertura dei link in una noopener il contesto. Pertanto, assicurati di includere rel="noopener" nel tuo Markup di ancoraggio <a> o aggiunta noopener al tuo Elenco Window.open() di funzionalità delle finestre.

start

Nella forma più semplice, la sintassi dei frammenti di testo è la seguente: il simbolo hash # seguito da :~:text= e infine start, che rappresenta con codifica percentuale il testo desiderato.

#:~:text=start

Ad esempio, supponi di voler collegare l'intestazione ECMAScript Modules in Web worker nella post del blog che annuncia le funzionalità di Chrome 80, l'URL in questo caso è:

https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules%20in%20Web%20Workers

Il frammento di testo viene enfatizzato in questo modo. Se fai clic sul link in un browser di supporto come Chrome, il frammento di testo viene evidenziato e scorre fino a visualizzare:

Frammento di testo visualizzato tramite scorrimento ed evidenziato.

start e end

E se volessi collegare l'intera sezione intitolata ECMAScript Modules in Web worker, non solo l'intestazione? La codifica percentuale dell'intero testo della sezione renderebbe l'URL risultante in modo impraticabile.

Per fortuna, c'è un modo migliore. Anziché l'intero testo, posso inquadrare il testo desiderato utilizzando la Sintassi start,end. Pertanto, specifico un paio di parole con codifica percentuale all'inizio del testo desiderato e un paio di parole con codifica percentuale alla fine del testo, separate di una virgola ,.

Ecco come:

https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules%20in%20Web%20Workers,ES%20Modules%20in%20Web%20Workers..

Per start, ho ECMAScript%20Modules%20in%20Web%20Workers seguito da una virgola , di ES%20Modules%20in%20Web%20Workers. come end. Quando fai clic su un browser di supporto come Chrome, l'intera sezione viene evidenziata e fatta scorrere per vederla:

Frammento di testo visualizzato tramite scorrimento ed evidenziato.

Ora ti chiederai quale sia la mia scelta tra start e end. In realtà, l'URL leggermente più breve https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules,Web%20Workers. con solo due parole su ogni lato avrebbe funzionato. Confronta start e end con valori precedenti.

Facendo un ulteriore passo in avanti e ora utilizzo una sola parola per start e end, puoi vediamo che sono nei guai. URL https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript,Workers. è ancora più corto, ma il frammento di testo evidenziato non è più quello desiderato in origine. La evidenziare le interruzioni alla prima occorrenza della parola Workers., che è corretta, ma non quella che da mettere in evidenza. Il problema è che la sezione desiderata non è identificata in modo univoco dal valori attuali di una parola start e end:

Frammento di testo non previsto che è stato visualizzato tramite scorrimento ed evidenziato.

prefix- e -suffix

Utilizzare valori sufficientemente lunghi per start e end è una soluzione per ottenere un link univoco. Tuttavia, in alcune situazioni non è possibile. Inoltre, perché ho scelto le Esempio: post del blog sulla versione di Chrome 80? La risposta è che in questa versione Frammenti di testo sono state introdotte:

Testo del post del blog: Frammenti URL di testo. Ora gli utenti o gli autori possono aggiungere link a una parte specifica di una pagina utilizzando un frammento di testo fornito in un URL. Quando la pagina viene caricata, il browser evidenzia il testo e fa scorrere il frammento per visualizzarlo. Ad esempio, l&#39;URL riportato di seguito carica una pagina wiki per &quot;Gatto&quot; e scorre fino ai contenuti elencati nel parametro &quot;text&quot;.
Estratto del post del blog sull'annuncio dei frammenti di testo.

Nota come nello screenshot sopra la parola "testo" appare quattro volte. La quarta occorrenza è con caratteri di codice verde. Per creare un link a questa parola specifica, impostare start a text. Poiché la parola "testo" è: beh, con una sola parola, non può esserci un end. E ora? La URL https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=text corrisponde alla prima occorrenza della parola "Text" già nell'intestazione:

Corrispondenza del frammento di testo alla prima occorrenza di "Testo".
di Gemini Advanced.

Per fortuna c'è una soluzione. In questi casi, posso specificare un prefix​- e un -suffix. La parola prima del carattere con il codice verde "text" è "the" e la parola dopo è "parameter". Nessuno dei altre tre occorrenze della parola "testo" contiene le stesse parole che lo circondano. Armati di questa funzionalità conoscenze, posso modificare l'URL precedente e aggiungere prefix- e -suffix. Come l'altro anch'essi devono essere codificati in percentuale e possono contenere più di una parola. https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=the-,text,-parameter. Per consentire al parser di identificare chiaramente prefix- e -suffix, è necessario separarli da start e da end facoltativo con un trattino -.

Corrispondenza del frammento di testo nell'occorrenza di "testo" desiderata.

La sintassi completa

Di seguito è riportata la sintassi completa dei frammenti di testo. Le parentesi quadre indicano un parametro facoltativo. I valori di tutti i parametri devono essere codificati in percentuale. Ciò è particolarmente importante per il trattino -, la e commerciale & e la virgola ,, quindi non vengono interpretati come parte del testo la sintassi della direttiva.

#:~:text=[prefix-,]start[,end][,-suffix]

prefix-, start, end e -suffix corrispondono a un solo testo all'interno di una singola elemento a livello di blocco, ma gli intervalli start,end completi possono coprire più blocchi. Ad esempio: :~:text=The quick,lazy dog non corrisponderà nell'esempio seguente, perché il valore iniziale string "The quick" non viene visualizzato all'interno di un singolo elemento senza interruzioni a livello di blocco:

<div>
  The
  <div></div>
  quick brown fox
</div>
<div>jumped over the lazy dog</div>

Tuttavia, corrisponde a questo esempio:

<div>The quick brown fox</div>
<div>jumped over the lazy dog</div>

Creazione di URL di frammenti di testo con un'estensione del browser

Creare manualmente URL di frammenti di testo è noioso, soprattutto quando si tratta di verificare che siano univoci. Se davvero lo desideri, la specifica ha alcuni suggerimenti ed elenca passaggi per la generazione di URL con frammenti di testo. Forniamo un'estensione per browser open source chiamata Crea un link al frammento di testo che ti consente di inserisci un link a un testo selezionandolo e facendo clic su "Copia link nel testo selezionato" nel contesto o dal menu Fogli Google. Questa estensione è disponibile per i seguenti browser:

di Gemini Advanced.
Link al frammento di testo del browser.

Più frammenti di testo in un URL

Tieni presente che in un URL possono essere presenti più frammenti di testo. I particolari frammenti di testo devono essere separate dalla e commerciale &. Ecco un esempio di link con tre frammenti di testo: 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

Tre frammenti di testo in un URL.

Combinazione di frammenti di elementi e testo

I frammenti di elementi tradizionali possono essere combinati con frammenti di testo. È perfetto avere entrambi nello stesso URL, ad esempio, per fornire una riserva significativa nel caso in cui il testo originale nella pagina in modo che il frammento di testo non corrisponda più. URL https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1:~:text=Give%20us%20feedback%20in%20our%20Product%20Forums. link al link Forniscici feedback nel nostro Sezione Forum dei prodotti contiene sia un frammento di elemento (HTML1) sia un frammento di testo (text=Give%20us%20feedback%20in%20our%20Product%20Forums.):

Collegamento con frammento elemento e frammento di testo.

La direttiva fragment

C'è un elemento della sintassi che non ho ancora spiegato: l'istruzione frammento :~:. Da evitare problemi di compatibilità con i frammenti di elementi URL esistenti, come mostrato sopra, La specifica dei frammenti di testo introduce il frammento . L'istruzione fragment è una parte del frammento dell'URL delimitata dalla sequenza di codice :~:. È riservata alle istruzioni dello user agent, ad esempio text=, e viene rimosso dall'URL. durante il caricamento, in modo che gli script dell'autore non vi possano interagire direttamente. Le istruzioni dello user agent sono chiamate anche istruzioni. Nel caso concreto, text= viene quindi chiamata istruzione di testo.

Rilevamento delle caratteristiche

Per rilevare il supporto, esegui un test per la proprietà fragmentDirective di sola lettura su document. Il frammento è un meccanismo che consente agli URL di specificare istruzioni rivolte al browser anziché documento. Ha lo scopo di evitare l'interazione diretta con lo script dell'autore, in modo che lo user agent futuro è possibile aggiungere istruzioni senza timore di apportare modifiche che provocano un errore ai contenuti esistenti. Uno. il potenziale esempio di queste aggiunte future potrebbe essere i suggerimenti di traduzione.

if ('fragmentDirective' in document) {
  // Text Fragments is supported.
}

Il rilevamento delle funzionalità è destinato principalmente ai casi in cui i link vengono generati dinamicamente (ad esempio, motori di ricerca) per evitare di fornire link con frammenti di testo a browser non supportati.

Definizione dello stile dei frammenti di testo

Per impostazione predefinita, i frammenti di testo in stile browser sono identici ai loro mark (in genere nero su giallo, i colori del sistema CSS per mark). Il foglio di stile dello user agent contiene codice CSS simile al seguente:

:root::target-text {
  color: MarkText;
  background: Mark;
}

Come puoi vedere, il browser espone uno pseudo-selettore ::target-text che puoi utilizzare per personalizzare l'evidenziazione applicata. Ad esempio, potresti progettare i frammenti di testo in modo che siano neri testo su uno sfondo rosso. Come sempre, assicurati di verifica il contrasto di colore pertanto lo stile di override non causi problemi di accessibilità e assicurati che l'evidenziazione che si distinguano visivamente dagli altri contenuti.

:root::target-text {
  color: black;
  background-color: red;
}

Policompilabilità

La funzionalità Frammenti di testo può essere riempita in qualche modo tramite polyfill. Forniamo un polyfill, che viene utilizzato internamente l'estensione, per i browser che non hanno forniscono un supporto integrato per Frammenti di testo in cui la funzionalità è implementata in JavaScript.

Il componente polyfill contiene un file fragment-generation-utils.js che puoi importare e utilizzare per generare link di frammenti di testo. Questo è descritto nell'esempio di codice riportato di seguito:

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);
}

Ottenere frammenti di testo a fini di analisi

Molti siti utilizzano il frammento per il routing, motivo per cui i browser rimuovono i frammenti di testo in modo da non interrompere quelle pagine. C'è un ha riconosciuto l'esigenza per esporre i link Frammenti di testo alle pagine, ad esempio per scopi di analisi, ma la soluzione proposta non è ancora implementata. Come soluzione alternativa per il momento, puoi utilizzare il codice seguente per estrarre le informazioni desiderate.

new URL(performance.getEntries().find(({ type }) => type === 'navigate').name).hash;

Sicurezza

Le istruzioni sui frammenti di testo vengono richiamate solo nelle navigazioni complete (non sulla stessa pagina) risultanti da a attivazione utente. Inoltre, per le navigazioni provenienti da un'origine diversa da quella della destinazione sarà necessario il valore che deve essere svolta in un noopener contesto, ad esempio che la pagina di destinazione sia sufficientemente isolata. Le istruzioni sui frammenti di testo sono solo applicata al frame principale. Ciò significa che non verrà eseguita la ricerca di testo all'interno di iframe e la navigazione non richiama un frammento di testo.

Privacy

È importante che le implementazioni della specifica Frammenti di testo non divulghino se un testo in una pagina è stato trovato o meno il frammento. Sebbene i frammenti di elementi siano completamente sotto il controllo autore della pagina originale, i frammenti di testo possono essere creati da chiunque. Ricorda come nel mio esempio riportato sopra non era possibile in alcun modo collegarsi all'intestazione ECMAScript Modules in Web worker, poiché <h1> non hanno un id, ma come chiunque, me compreso, potesse creare link a qualsiasi luogo creando con attenzione il frammento di testo?

Immagina di gestire una rete pubblicitaria evil-ads.example.com malvagia. Inoltre, immagina che in uno dei miei annunci iframe Ho creato dinamicamente un iframe multiorigine nascosto per dating.example.com con un tag di testo URL frammento dating.example.com#:~:text=Log%20Out dopo che l'utente ha interagito con l'annuncio. Se il testo "Esci" viene ritrovato, so che la vittima è attualmente ha eseguito l'accesso a dating.example.com, che potrei usare per la profilazione degli utenti. Poiché un testo ingenuo L'implementazione di frammenti potrebbe decidere che una corrispondenza corretta debba causare un'attivazione dello stato attivo, su evil-ads.example.com Ho potuto ascoltare l'evento blur e sapere quando si è verificata una corrispondenza. Nel Chrome abbiamo implementato frammenti di testo in modo tale che lo scenario descritto sopra non possa verificarsi.

Un altro attacco potrebbe essere lo sfruttamento del traffico di rete in base alla posizione di scorrimento. Suppongo di avere accesso a log del traffico di rete della mia vittima, ad esempio come amministratore di una intranet aziendale. Ora immagina esisteva un lungo documento delle Risorse umane Cosa fare se si soffre di... e poi un elenco di come burnout, ansia e così via. Potrei posizionare un pixel di monitoraggio accanto a ogni elemento dall'elenco di lettura. Se stabilisco che il caricamento temporale del documento coincide con il caricamento pixel di monitoraggio accanto, ad esempio, all'elemento burnout; in seguito, in qualità di amministratore della intranet, posso determinare che un dipendente ha fatto clic su un link di frammento di testo con :~:text=burn%20out che il dipendente potrebbe aver considerato riservato e non visibile a nessuno. Poiché questo esempio è in qualche modo inventato fin dall'inizio e poiché il suo sfruttamento richiede il rispetto di condizioni preliminari molto specifiche, Il team per la sicurezza di Chrome ha valutato il rischio dell'implementazione dello scorrimento della navigazione per essere gestibile. Altri user agent potrebbero decidere di mostrare invece un elemento UI con scorrimento manuale.

Per i siti che vogliono disattivare il servizio, Chromium supporta una Norme relative ai documenti valore di intestazione che possono inviare in modo che gli user agent non elaborino gli URL dei frammenti di testo.

Document-Policy: force-load-at-top

Disattivazione dei frammenti di testo

Il modo più semplice per disabilitare la funzionalità è utilizzare un'estensione che possa inserire una risposta HTTP come intestazioni ModHeader (non è un prodotto Google), per inserire l'intestazione di una risposta (not request) come segue:

Document-Policy: force-load-at-top

Un altro modo più coinvolgente per disattivare questa funzionalità consiste nell'utilizzare l'impostazione aziendale ScrollToTextFragmentEnabled Per farlo su macOS, incolla il comando seguente nel terminale.

defaults write com.google.Chrome ScrollToTextFragmentEnabled -bool false

Su Windows, segui la documentazione sul Assistenza nella Guida di Google Chrome Enterprise sito.

Per alcune ricerche, il motore di ricerca Google fornisce una risposta rapida o un riepilogo con un contenuto di un sito web pertinente. Questi snippet in primo piano hanno maggiori probabilità di essere visualizzati quando una ricerca è sotto forma di domanda. Facendo clic su uno snippet in primo piano, l'utente viene indirizzato direttamente dello snippet di testo nella pagina web di origine. Questa operazione funziona grazie agli URL di frammenti di testo creati automaticamente.

Pagina dei risultati del motore di ricerca Google che mostra uno snippet in primo piano. La barra di stato mostra l'URL dei frammenti di testo.
di Gemini Advanced.
Dopo aver fatto clic, la sezione pertinente della pagina viene visualizzata tramite scorrimento.

Conclusione

L'URL Frammenti di testo è una potente funzionalità per creare link a testo arbitrario nelle pagine web. Lo studioso la community può usarlo per fornire citazioni o link di riferimento estremamente precisi. I motori di ricerca possono utilizzare al link diretto ai risultati testuali sulle pagine. I siti di social network possono utilizzarlo per consentire agli utenti di condividere passaggi specifici di una pagina web anziché screenshot inaccessibili. Spero che inizierai utilizzando URL con frammenti di testo e li trovo utili quanto me. Assicurati di installare Link al browser Link al frammento di testo .

Ringraziamenti

I frammenti di testo sono stati implementati e specificati da Nick Burris e David Bokan, con contributi di Concedi Wang. Grazie a Joe Medley per la revisione completa di questo articolo. Immagine hero di Greg Rakozy su Rimuovi schermo.