Краткое руководство по внедрению общего хранилища и частного агрегирования

Этот документ представляет собой краткое руководство по использованию общего хранилища и частной агрегации. Вам понадобится понимание обоих API, поскольку общее хранилище хранит значения, а частное агрегирование создает агрегированные отчеты.

Целевая аудитория: рекламные технологии и поставщики аналитических услуг.

API общего хранилища

Чтобы предотвратить межсайтовое отслеживание, браузеры начали разделять все формы хранения, включая локальное хранилище, файлы cookie и т. д. Но есть случаи использования, когда требуется неразделенное хранилище. API общего хранилища обеспечивает неограниченный доступ на запись на различные сайты верхнего уровня с доступом на чтение с сохранением конфиденциальности.

Общее хранилище ограничено источником контекста (вызывающим объектом sharedStorage ).

Общее хранилище имеет ограничение емкости для каждого источника, при этом каждая запись ограничена максимальным количеством символов. Если предел достигнут, дальнейшие входные данные не сохраняются. Ограничения на хранение данных изложены в пояснении к общему хранилищу .

Вызов общего хранилища

Специалисты по рекламе могут писать в общее хранилище, используя JavaScript или заголовки ответов. Чтение из общего хранилища происходит только в изолированной среде JavaScript, называемой ворлетом.

  • Используя JavaScript, специалисты по рекламе могут выполнять определенные функции общего хранилища, такие как установка, добавление и удаление значений за пределами ворлета JavaScript. Однако такие функции, как чтение общего хранилища и выполнение частной агрегации, необходимо выполнять с помощью ворлета JavaScript. Методы, которые можно использовать вне ворлета JavaScript, можно найти в разделе Предлагаемая поверхность API — Вне ворлета .

    Методы, которые используются в рабочем листе во время операции, можно найти в разделе Предлагаемая поверхность API — В рабочем листе .

  • Использование заголовков ответов

    Подобно JavaScript, с помощью заголовков ответов можно выполнять только определенные функции, такие как установка, добавление и удаление значений в общем хранилище. Чтобы работать с общим хранилищем в заголовке ответа, в заголовок запроса необходимо включить Shared-Storage-Writable: ?1 .

    Чтобы инициировать запрос от клиента, запустите следующий код, в зависимости от выбранного вами метода:

    • Использование fetch()

      fetch("https://a.example/path/for/updates", {sharedStorageWritable: true});
      
    • Использование тега iframe или img

      <iframe src="https://a.example/path/for/updates" sharedstoragewritable></iframe>
      
    • Использование атрибута IDL с тегом iframe или img

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

Дополнительную информацию можно найти в разделе Общее хранилище: заголовки ответов .

Запись в общее хранилище

Чтобы выполнить запись в общее хранилище, вызовите метод sharedStorage.set() изнутри или снаружи ворлета JavaScript. При вызове извне ворлета данные записываются в источник контекста просмотра, из которого был выполнен вызов. При вызове изнутри ворлета данные записываются в источник контекста просмотра, который загрузил ворлет. Установленные ключи имеют срок действия 30 дней с момента последнего обновления.

Поле ignoreIfPresent является необязательным. Если он присутствует и имеет значение true , ключ не обновляется, если он уже существует. Срок действия ключа продлевается до 30 дней с момента вызова set() даже если ключ не обновляется.

Если доступ к общему хранилищу осуществляется несколько раз при одной загрузке страницы с одним и тем же ключом, значение ключа перезаписывается. Рекомендуется использовать sharedStorage.append() если ключ должен сохранять предыдущее значение.

  • Использование JavaScript

    Вне рабочего листа:

    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'}
    

    Аналогично внутри ворлета:

    sharedStorage.set('myKey', 'myValue1', { ignoreIfPresent: true });
    
  • Использование заголовков ответов

    Вы также можете писать в общее хранилище, используя заголовки ответов. Для этого используйте Shared-Storage-Write в заголовке ответа вместе со следующими командами:

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

    Несколько элементов могут быть разделены запятыми и могут сочетать set , append , delete clear .

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

Добавление значения

Вы можете добавить значение к существующему ключу, используя метод добавления. Если ключ не существует, вызов метода append() создает ключ и устанавливает значение. Это можно сделать с помощью JavaScript или заголовков ответов.

  • Использование JavaScript

    Чтобы обновить значения существующих ключей, используйте sharedStorage.append() внутри или снаружи ворлета.

    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'}
    

    Чтобы добавить внутрь ворлета:

    sharedStorage.append('myKey', 'myValue1');
    
  • Использование заголовков ответов

    Подобно настройке значения в общем хранилище, вы можете использовать Shared-Storage-Write в заголовке ответа для передачи пары ключ-значение.

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

Пакетное обновление значений

Вы можете вызвать sharedStorage.batchUpdate() внутри или снаружи ворлета JavaScript и передать ему упорядоченный массив методов, определяющих выбранные операции. Каждый конструктор метода принимает те же параметры, что и соответствующий ему отдельный метод для установки, добавления, удаления и очистки.

Вы можете установить блокировку, используя JavaScript или заголовок ответа:

  • Использование JavaScript

    Доступные методы JavaScript, которые можно использовать с batchUpdate() включают:

    • SharedStorageSetMethod() : записывает пару ключ-значение в общее хранилище.
    • SharedStorageAppendMethod() : добавляет значение к существующему ключу в общем хранилище.
    • SharedStorageDeleteMethod() : удаляет пару ключ-значение из общего хранилища.
    • SharedStorageClearMethod() : очищает все ключи в общем хранилище.
    sharedStorage.batchUpdate([
    new SharedStorageSetMethod('keyOne', 'valueOne'),
    new SharedStorageAppendMethod('keyTwo', 'valueTwo'),
    new SharedStorageDeleteMethod('keyThree'),
    new SharedStorageClearMethod()
    ]);
    
  • Использование заголовков ответов

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

Чтение из общего хранилища

Чтение из общего хранилища можно выполнять только внутри ворлета.

await sharedStorage.get('mykey');

Происхождение контекста просмотра, из которого был загружен модуль ворлета, определяет, чье общее хранилище будет считываться.

Удаление из общего хранилища

Удаление из общего хранилища можно выполнять с помощью JavaScript как внутри, так и за пределами ворлета, а также с помощью заголовков ответов с помощью delete() . Чтобы удалить все ключи одновременно, используйте clear() для любого из них.

  • Использование JavaScript

    Чтобы удалить из общего хранилища за пределами ворлета:

    window.sharedStorage.delete('myKey');
    

    Чтобы удалить из общего хранилища изнутри ворлета:

    sharedStorage.delete('myKey');
    

    Чтобы удалить все ключи одновременно за пределами ворлета:

    window.sharedStorage.clear();
    

    Чтобы удалить все ключи одновременно из ворлета:

    sharedStorage.clear();
    
  • Использование заголовков ответов

    Чтобы удалить значения с помощью заголовков ответа, вы также можете использовать Shared-Storage-Write в заголовке ответа, чтобы передать удаляемый ключ.

    delete;key="myKey"
    

    Чтобы удалить все ключи с помощью заголовков ответа:

    clear;
    

Чтение групп интересов защищенной аудитории из общего хранилища

Вы можете прочитать группы по интересам Защищенной аудитории из рабочего модуля общего хранилища. interestGroups() возвращает массив объектов StorageInterestGroup , включая атрибуты AuctionInterestGroup и GenerateBidInterestGroup .

В следующем примере показано, как читать группы интересов контекста просмотра и некоторые возможные операции, которые можно выполнить с полученными группами интересов. Две возможные операции: определение количества групп интересов и поиск группы интересов с наибольшим количеством ставок.

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

Происхождение контекста просмотра, из которого был загружен рабочий модуль, определяет происхождение групп интересов, считываемых по умолчанию. Чтобы узнать больше о источнике ворлета по умолчанию и о том, как его изменить, ознакомьтесь с разделом «Выполнение общего хранилища и частной агрегации» в пошаговом руководстве по API общего хранилища .

Параметры

Все методы модификатора общего хранилища поддерживают необязательный объект параметров в качестве последнего аргумента.

с замком

Опция withLock является необязательной. Если этот параметр указан, этот параметр указывает методу получить блокировку для определенного ресурса с помощью API веб-блокировок, прежде чем продолжить. Имя блокировки передается при запросе блокировки. Имя представляет собой ресурс, использование которого координируется между несколькими вкладками, рабочими процессами или кодом в источнике.

Параметр withLock можно использовать со следующими методами модификатора общего хранилища:

  • набор
  • добавить
  • удалить
  • прозрачный
  • пакетное обновление

Вы можете установить блокировку, используя JavaScript или заголовок ответа:

  • Использование JavaScript

    sharedStorage.set('myKey', 'myValue', { withLock: 'myResource' });
    
  • Использование заголовков ответов

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

Блокировки общего хранилища разделены по источнику данных. Блокировки не зависят от любых блокировок, полученных с помощью метода request() LockManager , независимо от того, находятся ли они в контексте window или worker . Тем не менее, они имеют ту же область действия, что и блокировки, полученные с помощью request() в контексте SharedStorageWorklet .

Хотя метод request() допускает различные параметры конфигурации, блокировки, полученные в общем хранилище, всегда соответствуют следующим настройкам по умолчанию:

  • mode: "exclusive" : никакие другие блокировки с таким же именем не могут удерживаться одновременно.
  • steal: false : существующие блокировки с таким же именем не снимаются для обработки других запросов.
  • ifAvailable: false : запросы ждут неопределенное время, пока блокировка не станет доступной.
Когда использовать withLock

Блокировки полезны в сценариях, когда одновременно может выполняться несколько рабочих программ (например, несколько рабочих программ на странице или несколько рабочих программ на разных вкладках), каждый из которых просматривает одни и те же данные. В этом случае рекомендуется обернуть соответствующий код ворлета блокировкой, чтобы гарантировать, что только один ворлет обрабатывает отчеты одновременно.

Другая ситуация, в которой блокировки полезны, — это наличие нескольких ключей, которые необходимо прочитать вместе в ворлете, и их состояние должно быть синхронизировано. В этом случае следует обернуть вызовы get блокировкой и обязательно получить ту же блокировку при записи на эти ключи.

Заказ замков

Из-за особенностей веб-блокировок методы модификаторов могут выполняться не в том порядке, который вы определили. Если первая операция требует блокировки и она задерживается, вторая операция может начаться до завершения первой.

Например:

// 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');
Пример изменения нескольких ключей

В этом примере используется блокировка, гарантирующая, что операции чтения и удаления внутри ворлета выполняются одновременно, предотвращая вмешательство извне ворлета.

В следующем примере modify-multiple-keys.js задаются новые значения для keyOne и keyTwo с помощью modify-lock а затем выполняется операция « modify-multiple-keys из ворлета:

// 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');

Затем в modify-multiple-keys-worklet.js вы можете запросить блокировку с помощью navigator.locks.request() для чтения и изменения ключей по мере необходимости.

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

Переключение контекста

Данные общего хранилища записываются в источник (например, https://example.adtech.com) контекста просмотра, из которого произошел вызов.

Когда вы загружаете сторонний код с помощью тега <script> , код выполняется в контексте просмотра средства внедрения. Таким образом, когда сторонний код вызываетsharedStorage.set sharedStorage.set() , данные записываются в общее хранилище внедряющего устройства. Когда вы загружаете сторонний код в iframe, код получает новый контекст просмотра, и его источником является источник iframe. Таким образом, вызов sharedStorage.set() сделанный из iframe, сохраняет данные в общем хранилище источника iframe.

Собственный контекст

Если на собственной странице есть встроенный сторонний код JavaScript, который вызывает sharedStorage.set() или sharedStorage.delete() , пара ключ-значение сохраняется в собственном контексте.

Данные хранятся на собственной странице со встроенным сторонним JavaScript.

Сторонний контекст

Пара ключ-значение может быть сохранена в рекламной технологии или стороннем контексте, создав iframe и вызвав set() или delete() в коде JavaScript изнутри iframe.

Данные, хранящиеся в контексте рекламных технологий или третьих лиц.

API частного агрегирования

Чтобы измерить агрегированные данные, хранящиеся в общем хранилище, вы можете использовать API частной агрегации.

Чтобы создать отчет, вызовите contributeToHistogram() внутри ворлета с сегментом и значением. Сегмент представлен 128-битным целым числом без знака, которое необходимо передать в функцию как BigInt . Значение представляет собой положительное целое число.

Для защиты конфиденциальности полезные данные отчета, содержащие сегмент и значение, шифруются при передаче, и их можно расшифровать и агрегировать только с помощью службы агрегирования.

Браузер также будет ограничивать вклад, который сайт может внести в выходной запрос. В частности, бюджет вклада ограничивает общее количество всех отчетов с одного сайта для данного браузера в заданном временном окне по всем сегментам. Если текущий бюджет превышен, отчет не будет сформирован.

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

Выполнение общего хранилища и частной агрегации

По умолчанию при использовании общего хранилища с createWorklet() источником раздела данных будет источник вызывающего контекста просмотра , а не источник самого сценария ворлета.

Чтобы изменить поведение по умолчанию, установите свойство dataOrigin при вызове createWorklet .

  • dataOrigin: "context-origin" : (по умолчанию) Данные хранятся в общем хранилище источника, вызывающего контекст просмотра.
  • dataOrigin: "script-origin" : данные хранятся в общем хранилище источника сценария рабочего листа. Для включения этого режима требуется согласие.
  • dataOrigin: "https://custom-data-origin.example" : данные хранятся в общем хранилище пользовательского источника данных. Для включения этого режима требуется согласие и согласие владельца пользовательского источника данных, как подробно описано в разделе «Происхождение пользовательского источника данных» .
sharedStorage.createWorklet(scriptUrl, {dataOrigin: "script-origin"});

Чтобы согласиться, при использовании "script-origin" или пользовательского источника конечная точка сценария должна ответить заголовком Shared-Storage-Cross-Origin-Worklet-Allowed . Для запросов из разных источников также следует включить CORS .

Shared-Storage-Cross-Origin-Worklet-Allowed : ?1
Access-Control-Allow-Origin: *

Вы также можете запускать сценарии перекрестного происхождения с использованием стороннего iframe, и в этом случае действия общего хранилища будут выполняться в стороннем контексте просмотра.

Использование iframe с перекрестным происхождением

Для вызова рабочего модуля общего хранилища необходим iframe.

В iframe объявления загрузите модуль ворлета, вызвав addModule() . Чтобы запустить метод, зарегистрированный в рабочем файле sharedStorageWorklet.js , в том же JavaScript-коде iframe вызовите sharedStorage.run() .

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

В сценарии ворлета вам нужно будет создать класс с методом асинхронного run и register его для запуска в iframe объявления. Внутри sharedStorageWorklet.js :

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

Использование запроса между источниками

Общее хранилище и частное агрегирование позволяют создавать рабочие модули из разных источников без необходимости использования iframe из разных источников.

Собственная страница также может вызывать вызов createWorklet() для конечной точки javascript между источниками. При создании ворлета вам нужно будет установить начало раздела данных ворлета так же, как и в сценарии-начало.

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

Конечная точка javascript с несколькими источниками должна будет ответить заголовками Shared-Storage-Cross-Origin-Worklet-Allowed и отметить, что CORS включен для запроса.

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

Рабочие модули, созданные с помощью createWorklet() будут иметь selectURL и run() . addModule() для этого недоступен.

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

Пользовательское происхождение данных

Если для dataOrigin задан действительный источник, владелец dataOrigin должен дать согласие на обработку общего хранилища для этого dataOrigin , разместив файл JSON, в котором указан источник сценария рабочего файла, по пути /.well-known/shared-storage/trusted-origins . Файл должен представлять собой массив объектов с ключами scriptOrigin и contextOrigin . Значения этих ключей могут быть строкой или массивом строк.

Создайте файл trusted-origins используя следующую информацию:

  • Контекст вызывающего абонента
  • Источник и URL-адрес сценария рабочего листа
  • Происхождение и владелец данных

В следующей таблице показано, как можно создать файл trusted-origins на основе этой информации:

Контекст вызывающего абонента URL-адрес сценария рабочего листа Происхождение данных Владелец данных JSON-файл доверенного происхождения владельца источника данных
https://publisher.example https://publisher.example/script.js контекст-происхождение https://publisher.example JSON не нужен
https://publisher.example https://ad.example/script.js происхождение сценария https://ad.example JSON не нужен
https://publisher.example https://cdn-ad.example/script.js https://ad.example https://ad.example
[{
  "scriptOrigin": "https://cdn-ad.example",
  "contextOrigin": "https://publisher.example"
}]
      
Любой абонент https://cdn-ad.example/script.js https://ad.example https://ad.example
[{
  "scriptOrigin": "https://cdn-ad.example",
  "contextOrigin": "*"
}]
      
https://publisher-a.example ИЛИ https://publisher-b.example https://cdn-ad.example/script.js https://ad.example https://ad.example
[{
  "scriptOrigin": "https://cdn-ad.example",
  "contextOrigin": [
      "https://publisher-a.example",
      "https://publisher-b.example"
  ]
}]
      
https://publisher.example https://cdn-a-ad.example/script.js ИЛИ https://cdn-b-ad.example/script.js https://ad.example https://ad.example
[{
  "scriptOrigin": [
    "https://cdn-a-ad.example",
    "https://cdn-b-ad.example"
  ],
  "contextOrigin": "https://publisher.example"
}]
      

Например, следующий JSON может быть размещен по адресу https://custom-data-origin.example/.well-known/shared-storage/trusted-origins и объединить все разрешенные обработчики данных общего хранилища для источника https://custom-data-origin.example .

[
  {
    "scriptOrigin": "https://script-origin.a.example",
    "contextOrigin": "https://context-origin.a.example"
  },
  {
    "scriptOrigin": "https://script-origin.b.example",
    "contextOrigin": [
      "https://context-origin.a.example",
      "https://context-origin.b.example"
    ]
}]

Следующие шаги

На следующих страницах объясняются важные аспекты API общего хранилища и частного агрегирования.

Ознакомившись с API-интерфейсами, вы можете начать собирать отчеты, которые отправляются в виде запроса POST на следующие конечные точки в формате JSON в теле запроса.

  • Отчеты об отладке — context-origin/.well-known/private-aggregation/debug/report-shared-storage
  • Отчеты – context-origin/.well-known/private-aggregation/report-shared-storage

После сбора отчетов вы можете протестировать их с помощью локального инструмента тестирования или настроить доверенную среду выполнения для службы агрегации, чтобы получать агрегированные отчеты.

Поделитесь своим отзывом

Вы можете поделиться своими отзывами об API и документации на GitHub.

,

Этот документ представляет собой краткое руководство по использованию общего хранилища и частной агрегации. Вам понадобится понимание обоих API, поскольку общее хранилище хранит значения, а частное агрегирование создает агрегированные отчеты.

Целевая аудитория: рекламные технологии и поставщики аналитических услуг.

API общего хранилища

Чтобы предотвратить межсайтовое отслеживание, браузеры начали разделять все формы хранения, включая локальное хранилище, файлы cookie и т. д. Но есть случаи использования, когда требуется неразделенное хранилище. API общего хранилища обеспечивает неограниченный доступ на запись на различные сайты верхнего уровня с доступом на чтение с сохранением конфиденциальности.

Общее хранилище ограничено источником контекста (вызывающим объектом sharedStorage ).

Общее хранилище имеет ограничение емкости для каждого источника, при этом каждая запись ограничена максимальным количеством символов. Если предел достигнут, дальнейшие входные данные не сохраняются. Ограничения на хранение данных изложены в пояснении к общему хранилищу .

Вызов общего хранилища

Специалисты по рекламе могут писать в общее хранилище, используя JavaScript или заголовки ответов. Чтение из общего хранилища происходит только в изолированной среде JavaScript, называемой ворлетом.

  • Используя JavaScript, специалисты по рекламе могут выполнять определенные функции общего хранилища, такие как установка, добавление и удаление значений за пределами ворлета JavaScript. Однако такие функции, как чтение общего хранилища и выполнение частной агрегации, необходимо выполнять с помощью ворлета JavaScript. Методы, которые можно использовать вне ворлета JavaScript, можно найти в разделе Предлагаемая поверхность API — Вне ворлета .

    Методы, которые используются в рабочем листе во время операции, можно найти в разделе Предлагаемая поверхность API — В рабочем листе .

  • Использование заголовков ответов

    Подобно JavaScript, с помощью заголовков ответов можно выполнять только определенные функции, такие как установка, добавление и удаление значений в общем хранилище. Чтобы работать с общим хранилищем в заголовке ответа, в заголовок запроса необходимо включить Shared-Storage-Writable: ?1 .

    Чтобы инициировать запрос от клиента, запустите следующий код, в зависимости от выбранного вами метода:

    • Использование fetch()

      fetch("https://a.example/path/for/updates", {sharedStorageWritable: true});
      
    • Использование тега iframe или img

      <iframe src="https://a.example/path/for/updates" sharedstoragewritable></iframe>
      
    • Использование атрибута IDL с тегом iframe или img

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

Дополнительную информацию можно найти в разделе Общее хранилище: заголовки ответов .

Запись в общее хранилище

Чтобы выполнить запись в общее хранилище, вызовите метод sharedStorage.set() изнутри или снаружи ворлета JavaScript. При вызове извне ворлета данные записываются в источник контекста просмотра, из которого был выполнен вызов. При вызове изнутри ворлета данные записываются в источник контекста просмотра, который загрузил ворлет. Установленные ключи имеют срок действия 30 дней с момента последнего обновления.

Поле ignoreIfPresent является необязательным. Если он присутствует и имеет значение true , ключ не обновляется, если он уже существует. Срок действия ключа продлевается до 30 дней с момента вызова set() даже если ключ не обновляется.

Если доступ к общему хранилищу осуществляется несколько раз при одной загрузке страницы с одним и тем же ключом, значение ключа перезаписывается. Рекомендуется использовать sharedStorage.append() если ключ должен сохранять предыдущее значение.

  • Использование JavaScript

    Вне рабочего листа:

    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'}
    

    Аналогично внутри ворлета:

    sharedStorage.set('myKey', 'myValue1', { ignoreIfPresent: true });
    
  • Использование заголовков ответов

    Вы также можете писать в общее хранилище, используя заголовки ответов. Для этого используйте Shared-Storage-Write в заголовке ответа вместе со следующими командами:

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

    Несколько элементов могут быть разделены запятыми и могут сочетать set , append , delete clear .

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

Добавление значения

Вы можете добавить значение к существующему ключу, используя метод добавления. Если ключ не существует, вызов метода append() создает ключ и устанавливает значение. Это можно сделать с помощью JavaScript или заголовков ответов.

  • Использование JavaScript

    Чтобы обновить значения существующих ключей, используйте sharedStorage.append() внутри или снаружи ворлета.

    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'}
    

    Чтобы добавить внутрь ворлета:

    sharedStorage.append('myKey', 'myValue1');
    
  • Использование заголовков ответов

    Подобно настройке значения в общем хранилище, вы можете использовать Shared-Storage-Write в заголовке ответа для передачи пары ключ-значение.

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

Пакетное обновление значений

Вы можете вызвать sharedStorage.batchUpdate() внутри или снаружи ворлета JavaScript и передать ему упорядоченный массив методов, определяющих выбранные операции. Каждый конструктор метода принимает те же параметры, что и соответствующий ему отдельный метод для установки, добавления, удаления и очистки.

Вы можете установить блокировку, используя JavaScript или заголовок ответа:

  • Использование JavaScript

    Доступные методы JavaScript, которые можно использовать с batchUpdate() включают:

    • SharedStorageSetMethod() : записывает пару ключ-значение в общее хранилище.
    • SharedStorageAppendMethod() : добавляет значение к существующему ключу в общем хранилище.
    • SharedStorageDeleteMethod() : удаляет пару ключ-значение из общего хранилища.
    • SharedStorageClearMethod() : очищает все ключи в общем хранилище.
    sharedStorage.batchUpdate([
    new SharedStorageSetMethod('keyOne', 'valueOne'),
    new SharedStorageAppendMethod('keyTwo', 'valueTwo'),
    new SharedStorageDeleteMethod('keyThree'),
    new SharedStorageClearMethod()
    ]);
    
  • Использование заголовков ответов

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

Чтение из общего хранилища

Чтение из общего хранилища можно выполнять только внутри ворлета.

await sharedStorage.get('mykey');

Происхождение контекста просмотра, из которого был загружен модуль ворлета, определяет, чье общее хранилище будет считываться.

Удаление из общего хранилища

Удаление из общего хранилища можно выполнять с помощью JavaScript как внутри, так и за пределами ворлета, а также с помощью заголовков ответов с помощью delete() . Чтобы удалить все ключи одновременно, используйте clear() для любого из них.

  • Использование JavaScript

    Чтобы удалить из общего хранилища за пределами ворлета:

    window.sharedStorage.delete('myKey');
    

    Чтобы удалить из общего хранилища изнутри ворлета:

    sharedStorage.delete('myKey');
    

    Чтобы удалить все ключи одновременно за пределами ворлета:

    window.sharedStorage.clear();
    

    Чтобы удалить все ключи одновременно из ворлета:

    sharedStorage.clear();
    
  • Использование заголовков ответов

    Чтобы удалить значения с помощью заголовков ответа, вы также можете использовать Shared-Storage-Write в заголовке ответа, чтобы передать удаляемый ключ.

    delete;key="myKey"
    

    Чтобы удалить все ключи с помощью заголовков ответа:

    clear;
    

Чтение групп интересов защищенной аудитории из общего хранилища

Вы можете прочитать группы по интересам Защищенной аудитории из рабочего модуля общего хранилища. interestGroups() возвращает массив объектов StorageInterestGroup , включая атрибуты AuctionInterestGroup и GenerateBidInterestGroup .

В следующем примере показано, как читать группы интересов контекста просмотра и некоторые возможные операции, которые можно выполнить с полученными группами интересов. Две возможные операции: определение количества групп интересов и поиск группы интересов с наибольшим количеством ставок.

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

Происхождение контекста просмотра, из которого был загружен рабочий модуль, определяет происхождение групп интересов, считываемых по умолчанию. Чтобы узнать больше о источнике ворлета по умолчанию и о том, как его изменить, ознакомьтесь с разделом «Выполнение общего хранилища и частной агрегации» в пошаговом руководстве по API общего хранилища .

Параметры

Все методы модификатора общего хранилища поддерживают необязательный объект параметров в качестве последнего аргумента.

с замком

Опция withLock является необязательной. Если этот параметр указан, этот параметр указывает методу получить блокировку для определенного ресурса с помощью API веб-блокировок, прежде чем продолжить. Имя блокировки передается при запросе блокировки. Имя представляет собой ресурс, использование которого координируется между несколькими вкладками, рабочими процессами или кодом в источнике.

Параметр withLock можно использовать со следующими методами модификатора общего хранилища:

  • набор
  • добавить
  • удалить
  • прозрачный
  • пакетное обновление

Вы можете установить блокировку, используя JavaScript или заголовок ответа:

  • Использование JavaScript

    sharedStorage.set('myKey', 'myValue', { withLock: 'myResource' });
    
  • Использование заголовков ответов

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

Блокировки общего хранилища разделены по источнику данных. Блокировки не зависят от любых блокировок, полученных с помощью метода request() LockManager , независимо от того, находятся ли они в контексте window или worker . Тем не менее, они имеют ту же область действия, что и блокировки, полученные с помощью request() в контексте SharedStorageWorklet .

Хотя метод request() допускает различные параметры конфигурации, блокировки, полученные в общем хранилище, всегда соответствуют следующим настройкам по умолчанию:

  • mode: "exclusive" : никакие другие блокировки с таким же именем не могут удерживаться одновременно.
  • steal: false : существующие блокировки с таким же именем не снимаются для обработки других запросов.
  • ifAvailable: false : запросы ждут неопределенное время, пока блокировка не станет доступной.
Когда использовать withLock

Блокировки полезны в сценариях, когда одновременно может выполняться несколько рабочих программ (например, несколько рабочих программ на странице или несколько рабочих программ на разных вкладках), каждый из которых просматривает одни и те же данные. В этом случае рекомендуется обернуть соответствующий код ворлета блокировкой, чтобы гарантировать, что только один ворлет обрабатывает отчеты одновременно.

Другая ситуация, в которой блокировки полезны, — это наличие нескольких ключей, которые необходимо прочитать вместе в ворлете, и их состояние должно быть синхронизировано. В этом случае следует обернуть вызовы get блокировкой и обязательно получить ту же блокировку при записи на эти ключи.

Заказ замков

Из-за особенностей веб-блокировок методы модификаторов могут выполняться не в том порядке, который вы определили. Если первая операция требует блокировки и она задерживается, вторая операция может начаться до завершения первой.

Например:

// 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');
Пример изменения нескольких ключей

В этом примере используется блокировка, гарантирующая, что операции чтения и удаления внутри ворлета выполняются одновременно, предотвращая вмешательство извне ворлета.

В следующем примере modify-multiple-keys.js задаются новые значения для keyOne и keyTwo с помощью modify-lock а затем выполняется операция « modify-multiple-keys из ворлета:

// 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');

Затем в modify-multiple-keys-worklet.js вы можете запросить блокировку с помощью navigator.locks.request() для чтения и изменения ключей по мере необходимости.

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

Переключение контекста

Данные общего хранилища записываются в источник (например, https://example.adtech.com) контекста просмотра, из которого произошел вызов.

Когда вы загружаете сторонний код с помощью тега <script> , код выполняется в контексте просмотра средства внедрения. Таким образом, когда сторонний код вызываетsharedStorage.set sharedStorage.set() , данные записываются в общее хранилище внедряющего устройства. Когда вы загружаете сторонний код в iframe, код получает новый контекст просмотра, и его источником является источник iframe. Таким образом, вызов sharedStorage.set() сделанный из iframe, сохраняет данные в общем хранилище источника iframe.

Собственный контекст

Если на собственной странице есть встроенный сторонний код JavaScript, который вызывает sharedStorage.set() или sharedStorage.delete() , пара ключ-значение сохраняется в собственном контексте.

Данные хранятся на собственной странице со встроенным сторонним JavaScript.

Сторонний контекст

Пара ключ-значение может быть сохранена в рекламной технологии или стороннем контексте, создав iframe и вызвав set() или delete() в коде JavaScript изнутри iframe.

Данные, хранящиеся в контексте рекламных технологий или третьих лиц.

API частного агрегирования

Чтобы измерить агрегированные данные, хранящиеся в общем хранилище, вы можете использовать API частной агрегации.

Чтобы создать отчет, вызовите contributeToHistogram() внутри ворлета с сегментом и значением. Сегмент представлен 128-битным целым числом без знака, которое необходимо передать в функцию как BigInt . Значение представляет собой положительное целое число.

Для защиты конфиденциальности полезные данные отчета, содержащие сегмент и значение, шифруются при передаче, и их можно расшифровать и агрегировать только с помощью службы агрегирования.

Браузер также будет ограничивать вклад, который сайт может внести в выходной запрос. В частности, бюджет вклада ограничивает общее количество всех отчетов с одного сайта для данного браузера в заданном временном окне по всем сегментам. Если текущий бюджет превышен, отчет не будет сформирован.

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

Выполнение общего хранилища и частной агрегации

По умолчанию при использовании общего хранилища с createWorklet() источником раздела данных будет источник вызывающего контекста просмотра , а не источник самого сценария ворлета.

Чтобы изменить поведение по умолчанию, установите свойство dataOrigin при вызове createWorklet .

  • dataOrigin: "context-origin" : (по умолчанию) Данные хранятся в общем хранилище источника, вызывающего контекст просмотра.
  • dataOrigin: "script-origin" : данные хранятся в общем хранилище источника сценария рабочего листа. Для включения этого режима требуется согласие.
  • dataOrigin: "https://custom-data-origin.example" : данные хранятся в общем хранилище пользовательского источника данных. Для включения этого режима требуется согласие и согласие владельца пользовательского источника данных, как подробно описано в разделе «Происхождение пользовательского источника данных» .
sharedStorage.createWorklet(scriptUrl, {dataOrigin: "script-origin"});

Чтобы согласиться, при использовании "script-origin" или пользовательского источника конечная точка сценария должна ответить заголовком Shared-Storage-Cross-Origin-Worklet-Allowed . Для запросов из разных источников также следует включить CORS .

Shared-Storage-Cross-Origin-Worklet-Allowed : ?1
Access-Control-Allow-Origin: *

Вы также можете запускать сценарии перекрестного происхождения с использованием стороннего iframe, и в этом случае действия общего хранилища будут выполняться в стороннем контексте просмотра.

Использование iframe с перекрестным происхождением

Для вызова рабочего модуля общего хранилища необходим iframe.

В iframe объявления загрузите модуль ворлета, вызвав addModule() . Чтобы запустить метод, зарегистрированный в рабочем файле sharedStorageWorklet.js , в том же JavaScript-коде iframe вызовите sharedStorage.run() .

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

В сценарии ворлета вам нужно будет создать класс с методом асинхронного run и register его для запуска в iframe объявления. Внутри sharedStorageWorklet.js :

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

Использование запроса между источниками

Общее хранилище и частное агрегирование позволяют создавать рабочие модули из разных источников без необходимости использования iframe из разных источников.

Собственная страница также может вызывать вызов createWorklet() для конечной точки javascript между источниками. При создании ворлета вам нужно будет установить начало раздела данных ворлета так же, как и в сценарии-начало.

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

Конечная точка javascript с несколькими источниками должна будет ответить заголовками Shared-Storage-Cross-Origin-Worklet-Allowed и отметить, что CORS включен для запроса.

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

Рабочие модули, созданные с помощью createWorklet() будут иметь selectURL и run() . addModule() для этого недоступен.

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

Пользовательское происхождение данных

Если для dataOrigin задан действительный источник, владелец dataOrigin должен дать согласие на обработку общего хранилища для этого dataOrigin , разместив файл JSON, в котором указан источник сценария рабочего файла, по пути /.well-known/shared-storage/trusted-origins . Файл должен представлять собой массив объектов с ключами scriptOrigin и contextOrigin . Значения для этих ключей могут быть либо строкой, либо массивом струн.

Создайте файл trusted-origins , используя следующую информацию:

  • Контекст вызывающего абонента
  • Рабочий сценарий происхождение и URL
  • Происхождение данных и владелец

Следующая таблица показывает, как вы можете построить файл trusted-origins на основе этой информации:

Контекст вызывающего абонента Рабочая сценария URL Данные происхождение Владелец данных Файл доверенного владельца Data Oruge Origins JSON
https: //publisher.example https: //publisher.example/script.js контекст-аоригин https: //publisher.example JSON не нужен
https: //publisher.example https: //ad.example/script.js сценарий-аоригин https: //ad.example JSON не нужен
https: //publisher.example https: //cdn-ad.example/script.js https: //ad.example https: //ad.example
[{
  "scriptOrigin": "https://cdn-ad.example",
  "contextOrigin": "https://publisher.example"
}]
      
Любой вызывающий абонент https: //cdn-ad.example/script.js https: //ad.example https: //ad.example
[{
  "scriptOrigin": "https://cdn-ad.example",
  "contextOrigin": "*"
}]
      
https: //publisher-a.example, или https: //publisher-b.example https: //cdn-ad.example/script.js https: //ad.example https: //ad.example
[{
  "scriptOrigin": "https://cdn-ad.example",
  "contextOrigin": [
      "https://publisher-a.example",
      "https://publisher-b.example"
  ]
}]
      
https: //publisher.example https: //cdn-a-ad.example/script.js или https: //cdn-b-ad.example/script.js https: //ad.example https: //ad.example
[{
  "scriptOrigin": [
    "https://cdn-a-ad.example",
    "https://cdn-b-ad.example"
  ],
  "contextOrigin": "https://publisher.example"
}]
      

Например, следующее JSON можно размещать по адресу https://custom-data-origin.example/.well-known/shared-storage/trusted-origins и объединяют все разрешенные процессоры данных общего хранилища для https://custom-data-origin.example .

[
  {
    "scriptOrigin": "https://script-origin.a.example",
    "contextOrigin": "https://context-origin.a.example"
  },
  {
    "scriptOrigin": "https://script-origin.b.example",
    "contextOrigin": [
      "https://context-origin.a.example",
      "https://context-origin.b.example"
    ]
}]

Следующие шаги

На следующих страницах объясняются важные аспекты общего хранилища и частного агрегации.

После того, как вы познакомитесь с API, вы можете начать собирать отчеты, которые отправляются в качестве запроса на следующие конечные точки в качестве JSON в органе запроса.

  • Отчеты отладки- context-origin/.well-known/private-aggregation/debug/report-shared-storage
  • Отчеты- context-origin/.well-known/private-aggregation/report-shared-storage

После того, как отчеты будут собраны, вы можете проверить, используя локальный инструмент тестирования или настроить надежную среду выполнения для службы агрегации, чтобы получить агрегированные отчеты.

Поделитесь своим отзывом

Вы можете поделиться своими отзывами об API и документации на GitHub.

,

Этот документ является руководством по использованию общего хранилища и частной агрегации. Вам понадобится понимание обоих API, потому что общее хранилище хранит ценности и частная агрегация создают обширные отчеты.

Целевая аудитория: рекламные технологии и поставщики измерений.

Общий API хранилища

Чтобы предотвратить перекрестное отслеживание, браузеры начали разделение всех форм хранения, включая локальное хранение, печенье и т. Д. Но есть варианты использования, когда требуется невозможное хранилище. API общего хранилища обеспечивает неограниченный доступ к записи на разных сайтах верхнего уровня с конфиденциальным доступом к чтению.

Общее хранилище ограничено контекстным происхождением (абонент sharedStorage ).

Общее хранилище имеет ограничение емкости на происхождение, причем каждая запись ограничивается максимальным количеством символов. Если предел достигнут, дальнейшие входы не хранятся. Пределы хранения данных изложены в общем объяснении хранилища .

Вызывая общее хранилище

AD Techs могут писать в общее хранилище, используя JavaScript или заголовки ответов. Чтение из общего хранилища происходит только в изолированной среде JavaScript, называемой работой.

  • Использование JavaScript AD Techs могут выполнять определенные функции общего хранения, такие как настройка, добавление и удаление значений за пределами рабочей формы JavaScript. Тем не менее, такие функции, как чтение общего хранилища и выполнение частной агрегации, должны быть выполнены с помощью рабочей формы JavaScript. Методы, которые можно использовать за пределами рабочей формы JavaScript, можно найти на предлагаемой поверхности API - за пределами рабочей силы .

    Методы, которые используются в рабочей форме во время операции, могут быть найдены на предлагаемой поверхности API - в рабочей форме .

  • Используя заголовки ответов

    Подобно JavaScript, только конкретные функции, такие как настройка, добавление и удаление значений в общем хранилище, могут быть выполнены с использованием заголовков ответов. Чтобы работать с общим хранилищем в заголовке ответа, Shared-Storage-Writable: ?1 должен быть включен в заголовок запроса».

    Чтобы инициировать запрос от клиента, запустите следующий код, в зависимости от выбранного вами метода:

    • Использование fetch()

      fetch("https://a.example/path/for/updates", {sharedStorageWritable: true});
      
    • Использование iframe или img -тег

      <iframe src="https://a.example/path/for/updates" sharedstoragewritable></iframe>
      
    • Использование атрибута IDL с iframe или img -тегом

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

Дополнительную информацию можно найти в общем хранилище: заголовки ответов .

Написание в общее хранилище

Чтобы написать в общее хранилище, вызовите sharedStorage.set() изнутри или за пределами рабочей силы JavaScript. Если они вызываются из -за пределов работы, данные записываются на происхождение контекста просмотра, из которого был сделан звонок. Если они вызываются изнутри, данные записываются на происхождение контекста просмотра, который загружал рабочуюля. Установленные ключи имеют дату истечения срока действия 30 дней после последнего обновления.

ignoreIfPresent поле является необязательным. Если присутствовать и установить на true , ключ не обновляется, если он уже существует. Срок действия ключа возобновляется до 30 дней после вызова set() даже если ключ не обновлен.

Если доступ к общему хранилищу несколько раз в одной и той же загрузке страницы с одной и той же клавиш, значение для ключа перезаписывается. Это хорошая идея, чтобы использовать sharedStorage.append() если ключ должен поддерживать предыдущее значение.

  • Использование JavaScript

    За пределами рабочей формы:

    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'}
    

    Точно так же, внутри рабочего:

    sharedStorage.set('myKey', 'myValue1', { ignoreIfPresent: true });
    
  • Используя заголовки ответов

    Вы также можете написать в общее хранилище, используя заголовки ответов. Для этого используйте в заголовке Shared-Storage-Write в заголовке ответов вместе со следующими командами:

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

    Несколько элементов могут быть разделены запятыми и могут set , append , delete и clear .

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

Добавление значения

Вы можете добавить значение к существующему ключу, используя метод добавления. Если ключ не существует, Calling append() создает ключ и устанавливает значение. Это может быть достигнуто с помощью JavaScript или заголовков ответов.

  • Использование JavaScript

    Для обновления значений существующих ключей используйте sharedStorage.append() либо внутри, так и за пределами рабочей формы.

    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'}
    

    Добавить в рабочую работу:

    sharedStorage.append('myKey', 'myValue1');
    
  • Используя заголовки ответов

    Подобно установлению значения в общем хранилище, вы можете использовать Shared-Storage-Write в заголовке ответа, чтобы пройти в паре ключевых значений.

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

Обновление партии значений

Вы можете позвонить в sharedStorage.batchUpdate() из -за или за пределами рабочей силы JavaScript и пройти в упорядоченном массиве методов, которые указывают выбранные операции. Каждый конструктор метода принимает те же параметры, что и соответствующий его индивидуальный метод для установки, добавления, удаления и очистки.

Вы можете установить блокировку, используя JavaScript или заголовок ответа:

  • Использование JavaScript

    Доступные методы JavaScript, которые можно использовать с batchUpdate() включают:

    • SharedStorageSetMethod() : пишет пару ключевых значений в общее хранилище.
    • SharedStorageAppendMethod() : добавляет значение к существующему ключу в общем хранилище.
    • SharedStorageDeleteMethod() : удаляет пару ключевых значений из общего хранилища.
    • SharedStorageClearMethod() : очищает все ключи в общем хранилище.
    sharedStorage.batchUpdate([
    new SharedStorageSetMethod('keyOne', 'valueOne'),
    new SharedStorageAppendMethod('keyTwo', 'valueTwo'),
    new SharedStorageDeleteMethod('keyThree'),
    new SharedStorageClearMethod()
    ]);
    
  • Используя заголовки ответов

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

Чтение из общего хранилища

Вы можете читать из общего хранилища только с рабочей силы.

await sharedStorage.get('mykey');

Происхождение контекста просмотра, от которого был загружен рабочая модуль, определяет, чье общее хранилище читается.

Удаление из общего хранилища

Вы можете выполнить удаления из общего хранилища, используя JavaScript либо внутри, так и за пределами рабочей формы или с помощью заголовков ответов с delete() . Чтобы удалить все ключи одновременно, используйте clear() из любого.

  • Использование JavaScript

    Удалить из общего хранилища из -за пределов работы:

    window.sharedStorage.delete('myKey');
    

    Чтобы удалить из общего хранилища изнутри рабочей формы:

    sharedStorage.delete('myKey');
    

    Чтобы сразу удалить все ключи из -за пределов работы:

    window.sharedStorage.clear();
    

    Чтобы удалить все клавиши сразу из рабочей формы:

    sharedStorage.clear();
    
  • Используя заголовки ответов

    Чтобы удалить значения, используя заголовки ответов, вы также можете использовать Shared-Storage-Write в заголовке ответа, чтобы пройти ключ, который будет удален.

    delete;key="myKey"
    

    Чтобы удалить все ключи, используя заголовки ответов:

    clear;
    

Чтение защищенных групп интересов аудитории из общего хранилища

Вы можете прочитать заинтересованные группы защищенной аудитории с общей работники хранения. Метод interestGroups() возвращает массив объектов Storage InterestGroup , включая атрибуты Auction InterestGroup и GenerateBideInterestGroup .

В следующем примере показано, как прочитать группы интересов контекста просмотра и некоторые возможные операции, которые могут быть выполнены в полученных группах интересов. Две возможные используемые операции - это нахождение количества групп заинтересованных групп и поиск процентной группы с наибольшим количеством ставок.

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

Происхождение контекста просмотра, из которого был загружен рабочий модуль, определяет происхождение групп интересов, которые читаются по умолчанию. Чтобы узнать больше о рабочем происхождении по умолчанию и о том, как его изменить, просмотрите раздел «Выполняющий общий хранение и частную агрегацию» в пошаговом руководстве общего хранилища .

Параметры

Все методы общего модификатора хранилища поддерживают дополнительный объект параметров в качестве последнего аргумента.

с ними

Вариант withLock не является обязательным. Если указано, эта опция инструктирует метод получить блокировку для определенного ресурса с помощью API Web Locks, прежде чем продолжить. Имя блокировки передается при запросе блокировки. Имя представляет ресурс, для которого координируется использование по нескольким вкладкам, работникам или коду в начале начала.

Опция withLock может использоваться со следующими методами общего модификатора хранения:

  • набор
  • добавлять
  • удалить
  • прозрачный
  • Обновление партии

Вы можете установить блокировку, используя JavaScript или заголовок ответа:

  • Использование JavaScript

    sharedStorage.set('myKey', 'myValue', { withLock: 'myResource' });
    
  • Используя заголовки ответов

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

Общие блокировки хранилища разделены на происхождение данных. Замки не зависят от любых замков, полученных с использованием метода LockManager () , независимо от того, находятся ли они в window или worker контексте. Тем не менее, они разделяют ту же сферу, что и замки, полученные с использованием request() в контексте SharedStorageWorkle .

В то время как метод request() допускает различные параметры конфигурации, блокировки, полученные в общем хранилище, всегда придерживаются следующих настроек по умолчанию:

  • mode: "exclusive" : никакие другие блокировки с тем же именем не могут быть выполнены одновременно.
  • steal: false : существующие замки с тем же именем не выпущены, чтобы удовлетворить другие запросы.
  • ifAvailable: false : запросы ждут до бесконечности, пока замок не станет доступен.
Когда использовать withLock

Замок полезны в сценариях, где могут быть несколько рабочих, работающих одновременно (например, несколько рабочих часов на странице или несколько рабочих, на разных вкладках), каждый из которых рассматривает одни и те же данные. В этом сценарии рекомендуется обернуть соответствующий рабочий код с помощью блокировки, чтобы гарантировать, что только одна рабочая такая работа обрабатывает отчеты одновременно.

Другая ситуация, в которой полезны блокировки, заключается в том, что есть несколько ключей, которые необходимо прочитать вместе в рабочей форме, и их состояние должно быть синхронизировано. В этом случае нужно обернуть звонки get с помощью блокировки и обязательно приобрести ту же блокировку при написании этих ключей.

Порядок замков

Из -за характера веб -блокировков методы модификатора могут не выполняться в определении, который вы определили. Если первая операция требует блокировки, и она задерживается, вторая операция может начаться до первого завершения.

Например:

// 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');
Изменить пример нескольких клавиш

В этом примере используется блокировка, чтобы гарантировать, что операции чтения и удаления в рабочей форме осуществляются вместе, предотвращая помехи вне рабочей формы.

Следующий пример modify-multiple-keys.js Устанавливает новые значения для keyOne и keyTwo с помощью modify-lock а затем выполняет операцию modify-multiple-keys с рабочей формы:

// 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');

Затем, в рамках modify-multiple-keys-worklet.js вы можете запросить блокировку с помощью navigator.locks.request() для чтения и изменения ключей по мере необходимости

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

Контекст переключение

Данные общего хранилища записываются в начало происхождения (например, https://example.adtech.com) контекста просмотра, из которого возник звонок.

Когда вы загружаете сторонний код, используя тег <script> , код выполняется в контексте просмотра Embedder. Следовательно, когда сторонний код вызывает sharedStorage.set() , данные записываются в общее хранилище Embedder. Когда вы загружаете сторонний код в IFRAME, код получает новый контекст просмотра, и его происхождение является происхождением iframe. Следовательно, вызов sharedStorage.set() выполненный из iframe, хранит данные в общее хранилище происхождения iframe.

Первозависимый контекст

Если первая страница внедряет сторонний код JavaScript, который вызывает sharedStorage.set() или sharedStorage.delete() , пара клавиш значения хранится в контексте первой стороны.

Данные, хранящиеся на первой странице со встроенным сторонним JavaScript.

Сторонний контекст

Пара ключевых значений может храниться в технологии AD или стороннего контекста, создав iframe и calling set() или delete() в коде JavaScript из iframe.

Данные, хранящиеся в контексте AD-Tech или сторонних.

Частная агрегация API

Для измерения агрегируемых данных, хранящихся в общем хранилище, вы можете использовать API частной агрегации.

Чтобы создать отчет, вызовите contributeToHistogram() внутри рабочего с ведром и ценностью. Ведро представлено неподписанным 128-разрядным целым числом, которое должно быть передано в функцию как BigInt . Значение является положительным целым числом.

Чтобы защитить конфиденциальность, полезная нагрузка отчета, которая содержит ведро и стоимость, зашифрована в транзите, и его можно расшифровать и агрегировать только с помощью службы агрегации.

Браузер также ограничит взносы, которые сайт может внести в выходной запрос. В частности, бюджет взносов ограничивает общую сумму всех отчетов с одного сайта для данного браузера в данном временном окне во всех ведрах. Если текущий бюджет превышен, отчет не будет сгенерирован.

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

Выполнение общего хранения и частного агрегации

По умолчанию при использовании общего хранилища с помощью createWorklet() происхождение раздела данных будет происхождение контекста просмотра , а не происхождение самого рабочего сценария.

Чтобы изменить поведение по умолчанию, установите свойство dataOrigin при вызове createWorklet .

  • dataOrigin: "context-origin" : (по умолчанию) Данные хранятся в общем хранении происхождения контекста просмотра.
  • dataOrigin: "script-origin" : данные хранятся в общем хранении происхождения рабочего сценария. Для включения этого режима требуется прибор.
  • dataOrigin: "https://custom-data-origin.example" : данные хранятся в общем хранилище индивидуального происхождения данных. Для включения этого режима и согласия от владельца ориентированного источника данных требуется привлечение, как подробно описано в индивидуальном происхождении .
sharedStorage.createWorklet(scriptUrl, {dataOrigin: "script-origin"});

Чтобы зарегистрироваться, при использовании "script-origin" или индивидуального происхождения конечная точка сценария должна отвечать с помощью заголовка Shared-Storage-Cross-Origin-Worklet-Allowed . Для перекрестных запросов CORS также следует включить.

Shared-Storage-Cross-Origin-Worklet-Allowed : ?1
Access-Control-Allow-Origin: *

Вы также можете запустить сценарии перекрестного происхождения, используя стороннюю Iframe, и в этом случае общие действия хранения будут находиться в контексте просмотра третьей стороны.

Использование перекрестного iframe

IFRAME необходим для вызова общей рабочей формы хранения.

В рекламе iframe загрузите модуль рабочего дня, вызывая addModule() . Чтобы запустить метод, который зарегистрирован в рабочем файле sharedStorageWorklet.js , в том же ad iframe javascript, вызовите sharedStorage.run() .

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

В рабочем сценарии вам нужно будет создать класс с помощью метода Async run и register его для запуска в ифраме объявления. Inside sharedStorageWorklet.js :

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

Использование перекрестного запроса

Общее хранилище и частное агрегация позволяет создавать перекрестные рабочие без необходимости в перекрестном происхождении iframes.

Первозависимая страница также может вызвать звонок createWorklet() в конечную точку JavaScript. Вам необходимо будет установить происхождение рабочей формы для данных, чтобы быть из сценариста при создании рабочей формы.

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

Конечная точка JavaScript межоригина должна будет ответить с помощью заголовков Shared-Storage-Cross-Origin-Worklet-Allowed и обратите внимание, что CORS включен для запроса.

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

Рабочие, созданные с использованием createWorklet() будут иметь selectURL и run() . addModule() недоступен для этого.

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

Пользовательское происхождение данных

Когда dataOrigin устанавливается на действительное происхождение, владелец dataOrigin должен согласиться на обработку общего хранилища для этого dataOrigin , размещая файл JSON, перечислимый источник рабочего сценария в PATH /.well-known/shared-storage/trusted-origins . Файл должен быть массивом объектов с клавишами scriptOrigin и contextOrigin . Значения для этих ключей могут быть либо строкой, либо массивом струн.

Создайте файл trusted-origins , используя следующую информацию:

  • Контекст вызывающего абонента
  • Рабочий сценарий происхождение и URL
  • Происхождение данных и владелец

Следующая таблица показывает, как вы можете построить файл trusted-origins на основе этой информации:

Контекст вызывающего абонента Рабочая сценария URL Данные происхождение Владелец данных Файл доверенного владельца Data Oruge Origins JSON
https: //publisher.example https: //publisher.example/script.js контекст-аоригин https: //publisher.example JSON не нужен
https: //publisher.example https: //ad.example/script.js сценарий-аоригин https: //ad.example JSON не нужен
https: //publisher.example https: //cdn-ad.example/script.js https: //ad.example https: //ad.example
[{
  "scriptOrigin": "https://cdn-ad.example",
  "contextOrigin": "https://publisher.example"
}]
      
Любой вызывающий абонент https: //cdn-ad.example/script.js https: //ad.example https: //ad.example
[{
  "scriptOrigin": "https://cdn-ad.example",
  "contextOrigin": "*"
}]
      
https: //publisher-a.example, или https: //publisher-b.example https: //cdn-ad.example/script.js https: //ad.example https: //ad.example
[{
  "scriptOrigin": "https://cdn-ad.example",
  "contextOrigin": [
      "https://publisher-a.example",
      "https://publisher-b.example"
  ]
}]
      
https: //publisher.example https: //cdn-a-ad.example/script.js или https: //cdn-b-ad.example/script.js https: //ad.example https: //ad.example
[{
  "scriptOrigin": [
    "https://cdn-a-ad.example",
    "https://cdn-b-ad.example"
  ],
  "contextOrigin": "https://publisher.example"
}]
      

Например, следующее JSON можно размещать по адресу https://custom-data-origin.example/.well-known/shared-storage/trusted-origins и объединяют все разрешенные процессоры данных общего хранилища для https://custom-data-origin.example .

[
  {
    "scriptOrigin": "https://script-origin.a.example",
    "contextOrigin": "https://context-origin.a.example"
  },
  {
    "scriptOrigin": "https://script-origin.b.example",
    "contextOrigin": [
      "https://context-origin.a.example",
      "https://context-origin.b.example"
    ]
}]

Следующие шаги

На следующих страницах объясняются важные аспекты общего хранилища и частного агрегации.

После того, как вы познакомитесь с API, вы можете начать собирать отчеты, которые отправляются в качестве запроса на следующие конечные точки в качестве JSON в органе запроса.

  • Отчеты отладки- context-origin/.well-known/private-aggregation/debug/report-shared-storage
  • Отчеты- context-origin/.well-known/private-aggregation/report-shared-storage

После того, как отчеты будут собраны, вы можете проверить, используя локальный инструмент тестирования или настроить надежную среду выполнения для службы агрегации, чтобы получить агрегированные отчеты.

Поделитесь своим отзывом

Вы можете поделиться своими отзывами об API и документации на GitHub.