Guida rapida all'implementazione dell'archiviazione condivisa e dell'aggregazione privata

Questo documento è una guida rapida all'utilizzo di Shared Storage e Private Aggregation. Devi conoscere entrambe le API perché lo spazio di archiviazione condiviso immagazzina i valori e l'aggregazione privata crea i report aggregabili.

Pubblico di destinazione:fornitori di tecnologia pubblicitaria e fornitori di servizi di misurazione.

API Shared Storage

Per impedire il monitoraggio tra siti, i browser hanno iniziato a partizionare tutte le forme di archiviazione, inclusi lo spazio di archiviazione locale, i cookie e così via. Tuttavia, esistono casi d'uso in cui è necessario uno spazio di archiviazione non partizionato. L'API Shared Storage fornisce accesso in scrittura illimitato a diversi siti di primo livello con accesso in lettura che tutela la privacy.

Lo spazio di archiviazione condiviso è limitato all'origine del contesto (l'autore della chiamata di sharedStorage).

Lo spazio di archiviazione condiviso ha un limite di capacità per origine, con ogni voce limitata a un numero massimo di caratteri. Se viene raggiunto il limite, non vengono memorizzati altri input. I limiti di spazio di archiviazione dei dati sono descritti nell'articolo esplicativo su Archiviazione condivisa.

Richiamo dello spazio di archiviazione condiviso

Gli esperti di tecnologia pubblicitaria possono scrivere in Shared Storage utilizzando JavaScript o intestazioni di risposta. La lettura dallo spazio di archiviazione condiviso avviene solo in un ambiente JavaScript isolated chiamato worklet.

  • Utilizzando JavaScript, gli esperti di tecnologia pubblicitaria possono eseguire funzioni specifiche di archiviazione condivisa, come l'impostazione, l'aggiunta e l'eliminazione di valori al di fuori di un worklet JavaScript. Tuttavia, funzioni come la lettura dello spazio di archiviazione condiviso e l'esecuzione dell'aggregazione privata devono essere completate tramite un worklet JavaScript. I metodi che possono essere utilizzati al di fuori di un worklet JavaScript sono disponibili in API Proposed Surface - Outside the worklet.

    I metodi utilizzati nel worklet durante un'operazione sono disponibili in Interfaccia API proposta - Nel worklet.

  • Utilizzare le intestazioni di risposta

    Come in JavaScript, solo funzioni specifiche come l'impostazione, l'aggiunta e l'eliminazione di valori in Shared Storage possono essere eseguite utilizzando le intestazioni di risposta. Per lavorare con lo spazio di archiviazione condiviso in un'intestazione di risposta, Shared-Storage-Writable: ?1 deve essere incluso nell'intestazione della richiesta.

    Per avviare una richiesta dal client, esegui il seguente codice, a seconda del metodo scelto:

    • In uso: fetch()

      fetch("https://a.example/path/for/updates", {sharedStorageWritable: true});
      
    • Utilizzare un tag iframe o img

      <iframe src="https://a.example/path/for/updates" sharedstoragewritable></iframe>
      
    • Utilizzare un attributo IDL con un tag iframe o img

      let iframe = document.getElementById("my-iframe");
      iframe.sharedStorageWritable = true;
      iframe.src = "https://a.example/path/for/updates";
      

Per ulteriori informazioni, consulta Spazio di archiviazione condiviso: intestazioni della risposta.

Scrittura nello spazio di archiviazione condiviso

Per scrivere in Spazio di archiviazione condiviso, chiama sharedStorage.set() dall'interno o dall'esterno di un worklet JavaScript. Se viene chiamato dall'esterno del worklet, i dati vengono scritti nell'origine del contesto di navigazione da cui è stata effettuata la chiamata. Se viene chiamato dall'interno del worklet, i dati vengono scritti nell'origine del contesto di navigazione che ha caricato il worklet. Le chiavi impostate hanno una data di scadenza di 30 giorni dall'ultimo aggiornamento.

Il campo ignoreIfPresent è facoltativo. Se presente e impostata su true, la chiave non viene aggiornata se esiste già. La scadenza della chiave viene rinnovata per 30 giorni dalla chiamata set() anche se la chiave non viene aggiornata.

Se si accede allo spazio di archiviazione condiviso più volte nello stesso caricamento di pagina con la stessa chiave, il valore della chiave viene sovrascritto. È consigliabile utilizzare sharedStorage.append() se la chiave deve mantenere il valore precedente.

  • Utilizzare JavaScript

    Al di fuori del worklet:

    window.sharedStorage.set('myKey', 'myValue1', { ignoreIfPresent: true });
    // Shared Storage: {'myKey': 'myValue1'}
    window.sharedStorage.set('myKey', 'myValue2', { ignoreIfPresent: true });
    // Shared Storage: {'myKey': 'myValue1'}
    window.sharedStorage.set('myKey', 'myValue2', { ignoreIfPresent: false });
    // Shared Storage: {'myKey': 'myValue2'}
    

    Analogamente, all'interno del worklet:

    sharedStorage.set('myKey', 'myValue1', { ignoreIfPresent: true });
    
  • Utilizzare le intestazioni di risposta

    Puoi anche scrivere in Shared Storage utilizzando le intestazioni di risposta. A tale scopo, utilizzaShared-Storage-Write nell'intestazione di risposta insieme ai seguenti comandi:

    Shared-Storage-Write : set;key="myKey";value="myValue";ignore_if_present
    
    Shared-Storage-Write : set;key="myKey";value="myValue";ignore_if_present=?0
    

    È possibile separare più elementi con una virgola e combinare set, append, delete e clear.

    Shared-Storage-Write :
    set;key="hello";value="world";ignore_if_present, set;key="good";value="bye"
    

Appendere un valore

Puoi aggiungere un valore a una chiave esistente utilizzando il metodo append. Se la chiave non esiste, la chiamata a append() la crea e imposta il valore. Questo può essere ottenuto utilizzando JavaScript o le intestazioni di risposta.

  • Utilizzare JavaScript

    Per aggiornare i valori delle chiavi esistenti, utilizza sharedStorage.append() dall'interno o dall'esterno del worklet.

    window.sharedStorage.append('myKey', 'myValue1');
    // Shared Storage: {'myKey': 'myValue1'}
    window.sharedStorage.append('myKey', 'myValue2');
    // Shared Storage: {'myKey': 'myValue1myValue2'}
    window.sharedStorage.append('anotherKey', 'hello');
    // Shared Storage: {'myKey': 'myValue1myValue2', 'anotherKey': 'hello'}
    

    Per accodare all'interno del worklet:

    sharedStorage.append('myKey', 'myValue1');
    
  • Utilizzare le intestazioni di risposta

    Analogamente all'impostazione di un valore in Shared Storage, puoi utilizzare Shared-Storage-Write nell'intestazione di risposta per passare la coppia chiave-valore.

    Shared-Storage-Write : append;key="myKey";value="myValue2"
    

Aggiornamento batch dei valori

Puoi chiamare sharedStorage.batchUpdate() dall'interno o dall'esterno di un worklet JavaScript e passare un array ordinato di metodi che specificano le operazioni scelte. Ogni costruttore di metodi accetta gli stessi parametri del singolo metodo corrispondente per set, append, delete e clear.

Puoi impostare il blocco utilizzando JavaScript o l'intestazione della risposta:

  • Utilizzare JavaScript

    I metodi JavaScript disponibili che possono essere utilizzati con batchUpdate() includono:

    • SharedStorageSetMethod(): scrive una coppia chiave-valore nello spazio di archiviazione condiviso.
    • SharedStorageAppendMethod(): aggiunge un valore a una chiave esistente in Shared Storage.
    • SharedStorageDeleteMethod(): elimina una coppia chiave-valore dallo spazio di archiviazione condiviso.
    • SharedStorageClearMethod(): cancella tutte le chiavi nello spazio di archiviazione condiviso.
    sharedStorage.batchUpdate([
    new SharedStorageSetMethod('keyOne', 'valueOne'),
    new SharedStorageAppendMethod('keyTwo', 'valueTwo'),
    new SharedStorageDeleteMethod('keyThree'),
    new SharedStorageClearMethod()
    ]);
    
  • Utilizzare le intestazioni di risposta

    Shared-Storage-Write : batchUpdate;methods="set;key=keyOne;value=valueOne, append;key=keyTwo;value=valueTwo,delete;key=keyThree,clear"
    

Lettura dallo spazio di archiviazione condiviso

Puoi leggere dallo spazio di archiviazione condiviso solo da un worklet.

await sharedStorage.get('mykey');

L'origine del contesto di navigazione da cui è stato caricato il modulo del worklet determina lo spazio di archiviazione condiviso di chi viene letto.

Eliminazione da Shared Storage

Puoi eseguire eliminazioni da Shared Storage utilizzando JavaScript dall'interno o dall'esterno del worklet oppure utilizzando le intestazioni di risposta con delete(). Per eliminare tutte le chiavi contemporaneamente, utilizza clear() da una delle due.

  • Utilizzare JavaScript

    Per eliminare elementi dallo spazio di archiviazione condiviso dall'esterno del worklet:

    window.sharedStorage.delete('myKey');
    

    Per eliminare un elemento dallo spazio di archiviazione condiviso dall'interno del worklet:

    sharedStorage.delete('myKey');
    

    Per eliminare tutte le chiavi contemporaneamente dall'esterno del worklet:

    window.sharedStorage.clear();
    

    Per eliminare tutte le chiavi contemporaneamente dall'interno del worklet:

    sharedStorage.clear();
    
  • Utilizzare le intestazioni di risposta

    Per eliminare i valori utilizzando le intestazioni di risposta, puoi anche utilizzare Shared-Storage-Write nell'intestazione di risposta per passare la chiave da eliminare.

    delete;key="myKey"
    

    Per eliminare tutte le chiavi utilizzando le intestazioni di risposta:

    clear;
    

Lettura dei gruppi di interesse di Protected Audience dallo spazio di archiviazione condiviso

Puoi leggere i gruppi di interesse di Protected Audience da un worklet di archiviazione condivisa. Il metodo interestGroups() restituisce un array di oggetti StorageInterestGroup, inclusi gli attributi AuctionInterestGroup e GenerateBidInterestGroup.

L'esempio seguente mostra come leggere i gruppi di interesse del contesto di navigazione e alcune possibili operazioni che possono essere eseguite sui gruppi di interesse recuperati. Le due possibili operazioni utilizzate sono trovare il numero di gruppi di interesse e trovare il gruppo di interesse con il numero di offerte più elevato.

async function analyzeInterestGroups() {
  const interestGroups = await interestGroups();
  numIGs = interestGroups.length;
  maxBidCountIG = interestGroups.reduce((max, cur) => { return cur.bidCount > max.bidCount ? cur : max; }, interestGroups[0]);
  console.log("The IG that bid the most has name " + maxBidCountIG.name);
}

L'origine del contesto di navigazione da cui è stato caricato il modulo del worklet determina l'origine dei gruppi di interesse letti per impostazione predefinita. Per scoprire di più sull'origine del worklet predefinita e su come modificarla, consulta la sezione Esecuzione di archiviazione condivisa e aggregazione privata nella procedura dettagliata dell'API Shared Storage.

Opzioni

Tutti i metodi di modifica dello spazio di archiviazione condiviso supportano un oggetto opzionale options come ultimo argomento.

withLock

L'opzione withLock è facoltativa. Se specificata, questa opzione indica al metodo di acquisire un blocco per la risorsa definita utilizzando l'API Web Locks prima di procedere. Quando viene richiesta la serratura, viene passato un nome. Il nome rappresenta una risorsa per cui l'utilizzo è coordinato su più schede,worker o codice all'interno dell'origine.

L'opzione withLock può essere utilizzata con i seguenti metodi di modifica dello spazio di archiviazione condiviso:

  • imposta
  • Aggiunta
  • elimina
  • cancella
  • aggiornamento batch

Puoi impostare il blocco utilizzando JavaScript o l'intestazione della risposta:

  • Utilizzare JavaScript

    sharedStorage.set('myKey', 'myValue', { withLock: 'myResource' });
    
  • Utilizzare le intestazioni di risposta

    Shared-Storage-Write : set;key="myKey";value="myValue";with_lock="myResource"
    

I blocchi di archiviazione condivisa sono suddivisi in base all'origine dei dati. I blocchi sono indipendenti da eventuali blocchi ottenuti utilizzando il metodo request() di LockManager, indipendentemente dal fatto che si trovino in un contesto window o worker. Tuttavia, condividono lo stesso ambito delle chiavi ottenute utilizzando request() nel contesto di SharedStorageWorklet.

Sebbene il metodo request() consenta varie opzioni di configurazione, le chiavi acquisite in Shared Storage rispettano sempre le seguenti impostazioni predefinite:

  • mode: "exclusive": non è possibile avere contemporaneamente altre serrature con lo stesso nome.
  • steal: false: le serrature esistenti con lo stesso nome non vengono rilasciate per soddisfare altre richieste.
  • ifAvailable: false: le richieste rimangono in attesa a tempo indeterminato finché il blocco non diventa disponibile.
Quando utilizzare withLock

I blocchi sono utili in scenari in cui potrebbero essere in esecuzione più worklet contemporaneamente (ad es. più worklet in una pagina o in schede diverse), ognuno dei quali esamina gli stessi dati. In questo caso, è buona norma racchiudere il codice del worklet pertinente con un blocco per assicurarti che solo un worklet elabori i report alla volta.

Un'altra situazione in cui le serrature sono utili è se ci sono più chiavi che devono essere lette insieme in un worklet e il loro stato deve essere sincronizzato. In questo caso, è necessario racchiudere le chiamate get con un blocco e assicurarsi di acquisire lo stesso blocco quando si scrive in queste chiavi.

Ordine delle serrature

A causa della natura dei blocchi web, i metodi dei modificatori potrebbero non essere eseguiti nell'ordine definito. Se la prima operazione richiede un blocco ed è in ritardo, la seconda operazione potrebbe iniziare prima del termine della prima.

Ad esempio:

// This line might pause until the lock is available.
sharedStorage.set('keyOne', 'valueOne', { withLock: 'resource-lock' });

// This line will run right away, even if the first one is still waiting.
sharedStorage.set('keyOne', 'valueTwo');
Esempio di modifica di più chiavi

Questo esempio utilizza un blocco per garantire che le operazioni di lettura ed eliminazione all'interno del worklet vengano eseguite contemporaneamente, impedendo interferenze dall'esterno del worklet.

Il seguente esempio di modify-multiple-keys.js imposta nuovi valori per keyOne e keyTwo con modify-lock, quindi esegue l'operazione modify-multiple-keys dal worklet:

// modify-multiple-keys.js
sharedStorage.batchUpdate([
    new SharedStorageSetMethod('keyOne', calculateValueFor('keyOne')),
    new SharedStorageSetMethod('keyTwo', calculateValueFor('keyTwo'))
], { withLock: 'modify-lock' });

const modifyWorklet = await sharedStorage.createWorklet('modify-multiple-keys-worklet.js');
await modifyWorklet.run('modify-multiple-keys');

Poi, all'interno di modify-multiple-keys-worklet.js puoi richiedere la serratura utilizzando navigator.locks.request() per leggere e modificare le chiavi in base alle necessità

// modify-multiple-keys-worklet.js
class ModifyMultipleKeysOperation {
  async run(data) {
    await navigator.locks.request('modify-lock', async (lock) => {
      const value1 = await sharedStorage.get('keyOne');
      const value2 = await sharedStorage.get('keyTwo');

      // Do something with `value1` and `value2` here.

      await sharedStorage.delete('keyOne');
      await sharedStorage.delete('keyTwo');
    });
  }
}
register('modify-multiple-keys', ModifyMultipleKeysOperation);

Cambio di contesto

I dati di archiviazione condivisa vengono scritti nell'origine (ad es. https://example.adtech.com) del contesto di navigazione da cui ha avuto origine la chiamata.

Quando carichi il codice di terze parti utilizzando un tag <script>, il codice viene eseguito nel contesto di navigazione dell'embedder. Pertanto, quando il codice di terze parti chiama sharedStorage.set(), i dati vengono scritti nello spazio di archiviazione condiviso dell'utente che ha eseguito l'embed. Quando carichi il codice di terze parti all'interno di un iframe, il codice riceve un nuovo contesto di navigazione e la relativa origine è l'origine dell'iframe. Pertanto, la chiamata sharedStorage.set() effettuata dall'iframe archivia i dati nello stoccaggio condiviso dell'origine dell'iframe.

Contesto proprietario

Se una pagina proprietaria ha incorporato codice JavaScript di terze parti che chiama sharedStorage.set() o sharedStorage.delete(), la coppia chiave-valore viene memorizzata nel contesto proprietario.

Dati archiviati in una pagina proprietaria con JavaScript di terze parti incorporato.

Contesto di terze parti

La coppia chiave-valore può essere archiviata nel contesto ad tech o di terze parti creando un iframe e chiamando set() o delete() nel codice JavaScript dall'interno dell'iframe.

Dati archiviati nel contesto ad tech o di terze parti.

API Private Aggregation

Per misurare i dati aggregabili archiviati nello spazio di archiviazione condiviso, puoi utilizzare l'API PrivateAggregation.

Per creare un report, chiama contributeToHistogram() all'interno di un worklet con un bucket e un valore. Il bucket è rappresentato da un numero intero non firmato a 128 bit che deve essere passato alla funzione come BigInt. Il valore è un numero intero positivo.

Per proteggere la privacy, il payload del report, che contiene il bucket e il valore, viene criptato in transito e può essere decriptato e aggregato solo utilizzando il servizio di aggregazione.

Il browser limiterà anche i contributi che un sito può apportare a una query di output. Nello specifico, il budget per i contributi limita il totale di tutti i report di un singolo sito per un determinato browser in una determinata finestra temporale in tutti i bucket. Se il budget corrente viene superato, non verrà generato un report.

privateAggregation.contributeToHistogram({
  bucket: BigInt(myBucket),
  value: parseInt(myBucketValue)
});

Eseguire lo spazio di archiviazione condiviso e l'aggregazione privata

Devi creare un worklet per accedere ai dati dallo spazio di archiviazione condiviso. Per farlo, chiama createWorklet() con l'URL del worklet. Per impostazione predefinita, quando utilizzi lo spazio di archiviazione condiviso con createWorklet(), l'origine della partizione di dati sarà l'origine del contesto di navigazione invocante, non l'origine dello script del worklet stesso.

Per modificare il comportamento predefinito, imposta la proprietà dataOrigin quando chiami createWorklet.

  • dataOrigin: "context-origin": (valore predefinito) i dati vengono archiviati nello spazio di archiviazione condiviso dell'origine del contesto di navigazione che ha eseguito l'invocazione.
  • dataOrigin: "script-origin": i dati vengono archiviati nello spazio di archiviazione condiviso dell'origine dello script del worklet. Tieni presente che per attivare questa modalità è necessaria l'attivazione.
sharedStorage.createWorklet(scriptUrl, {dataOrigin: "script-origin"});

Per attivare questa funzionalità, quando utilizzi "script-origin", l'endpoint dello script dovrà rispondere con l'intestazione Shared-Storage-Cross-Origin-Worklet-Allowed. Tieni presente che CORS deve essere abilitato per le richieste cross-origin.

Shared-Storage-Cross-Origin-Worklet-Allowed : ?1

Utilizzo di iframe cross-origin

Per richiamare il worklet dello spazio di archiviazione condiviso è necessario un iframe.

Nell'iframe dell'annuncio, carica il modulo worklet chiamando addModule(). Per eseguire il metodo registrato nel file worklet sharedStorageWorklet.js, nello stesso JavaScript iframe dell'annuncio, chiama sharedStorage.run().

const sharedStorageWorklet = await window.sharedStorage.createWorklet(
  'https://any-origin.example/modules/sharedStorageWorklet.js'
);
await sharedStorageWorklet.run('shared-storage-report', {
  data: { campaignId: '1234' },
});

Nello script del worklet, dovrai creare una classe con un metodo run asincrono e register per eseguirlo nell'iframe dell'annuncio. All'interno sharedStorageWorklet.js:

class SharedStorageReportOperation {
  async run(data) {
    // Other code goes here.
    bucket = getBucket(...);
    value = getValue(...);
    privateAggregation.contributeToHistogram({
      bucket,
      value
    });
  }
}
register('shared-storage-report', SharedStorageReportOperation);

Utilizzo di una richiesta cross-origin

Lo spazio di archiviazione condiviso e l'aggregazione privata consentono di creare worklet cross-origin senza la necessità di iframe cross-origin.

La pagina proprietaria può anche invocare una chiamata createWorklet() all'endpoint JavaScript cross-origin. Quando crei il worklet, devi impostare l'origine della partizione di dati del worklet sull'origine dello script.

async function crossOriginCall() {
  const privateAggregationWorklet = await sharedStorage.createWorklet(
    'https://cross-origin.example/js/worklet.js',
    { dataOrigin: 'script-origin' }
  );
  await privateAggregationWorklet.run('pa-worklet');
}
crossOriginCall();

L'endpoint JavaScript cross-origin dovrà rispondere con le intestazioniShared-Storage-Cross-Origin-Worklet-Allowed e tenere presente che CORS è abilitato per la richiesta.

Shared-Storage-Cross-Origin-Worklet-Allowed : ?1

I worklet creati utilizzando createWorklet() avranno selectURL e run(). addModule() non è disponibile per questa operazione.

class CrossOriginWorklet {
  async run(data){
    // Other code goes here.
    bucket = getBucket(...);
    value = getValue(...);
    privateAggregation.contributeToHistogram({
      bucket,
      value
    });
  }
}

Passaggi successivi

Le pagine seguenti spiegano aspetti importanti delle API Private Aggregation e Shared Storage.

Una volta acquisita familiarità con le API, puoi iniziare a raccogliere i report, che vengono inviati come richiesta POST ai seguenti endpoint come JSON nel corpo della richiesta.

  • Report di debug - context-origin/.well-known/private-aggregation/debug/report-shared-storage
  • Report - context-origin/.well-known/private-aggregation/report-shared-storage

Una volta raccolti i report, puoi eseguire il test utilizzando lo strumento di test locale o configurare l'ambiente di esecuzione attendibile per il servizio di aggregazione per ottenere i report aggregati.

Condividi il tuo feedback

Puoi condividere il tuo feedback sulle API e sulla documentazione su GitHub.