本文件是使用 Shared Storage 和 Private Aggregation 的快速入門指南。您必須瞭解這兩個 API,因為 Shared Storage 會儲存值,而 Private Aggregation 會建立可匯總的報表。
目標對象:廣告技術和評估服務供應商。
Shared Storage API
為了防止跨網站追蹤,瀏覽器已開始分割所有形式的儲存空間,包括本機儲存空間、Cookie 等。但有些用途需要使用未分割的儲存空間。Shared Storage API 可在不同頂層網站上提供無限的寫入存取權,並保留隱私權保護的讀取權。
共用儲存空間僅限於內容來源 (sharedStorage
的呼叫端)。
Shared Storage 每個來源的容量上限為 1000 個字元,每個項目的字元上限為 100 個半形字元。如果達到上限,系統就不會再儲存其他輸入內容。如要瞭解資料儲存空間限制,請參閱共用儲存空間說明。
叫用共用儲存空間
廣告技術人員可以使用 JavaScript 或回應標頭寫入共用儲存空間。只有在名為 worklet 的隔離 JavaScript 環境中,才會從共用儲存空間讀取資料。
使用 JavaScript 廣告技術可執行特定的共用儲存空間函式,例如在 JavaScript 工作區外設定、附加及刪除值。不過,讀取共用儲存空間和執行私人匯總等函式必須透過 JavaScript 工作區完成。您可以在「建議的 API 途徑 - 工作區外」一節中,找到可在 JavaScript 工作區外使用的各項方法。
您可以在「建議的 API 途徑 - 在 worklet 中」一節中,查看在作業期間在 worklet 中使用的各項方法。
使用回應標頭
與 JavaScript 類似,只有特定函式 (例如在 Shared Storage 中設定、附加及刪除值) 才能使用回應標頭執行。如要在回應標頭中使用共用儲存空間,請務必在要求標頭中加入
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";
詳情請參閱「共用儲存空間:回應標頭」。
寫入共用儲存空間
如要寫入 Shared Storage,請從 JavaScript 工作區內或外呼叫 sharedStorage.set()
。如果從工作單元外部呼叫,資料會寫入呼叫來源的瀏覽內容來源。如果從工作區塊內呼叫,資料會寫入載入工作區塊的瀏覽內容來源。設定的鍵會在最後一次更新後的 30 天到期。
ignoreIfPresent
為選填欄位。如果鍵已存在且已設為 true
,則系統不會更新該鍵。即使未更新金鑰,金鑰到期日也會從 set()
呼叫後延長至 30 天。
如果在同一個網頁載入中使用相同的鍵多次存取共用儲存空間,系統會覆寫該鍵的值。如果鍵需要保留先前的值,建議使用 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 中設定值類似,您可以在回應標頭中使用
Shared-Storage-Write
傳入鍵/值組合。Shared-Storage-Write : append;key="myKey";value="myValue2"
批次更新值
您可以在 JavaScript 工作區內或外呼叫 sharedStorage.batchUpdate()
,並傳入指定所選作業的排序方法陣列。每個方法建構函式都會接受與其對應的個別方法相同的參數,用於設定、附加、刪除和清除。
您可以使用 JavaScript 或回應標頭設定鎖定:
使用 JavaScript
可與
batchUpdate()
搭配使用的 JavaScript 方法包括: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 從工作單元內部或外部執行刪除 Shared Storage 的作業,也可以使用 delete()
搭配回應標頭執行刪除作業。如要一次刪除所有鍵,請使用任一鍵的 clear()
。
使用 JavaScript
如要從工作區塊外部刪除共用儲存空間中的資料,請按照下列步驟操作:
window.sharedStorage.delete('myKey');
如何從小程式內部刪除共用儲存空間:
sharedStorage.delete('myKey');
如要從工作單元外部一次刪除所有鍵,請按照下列步驟操作:
window.sharedStorage.clear();
如要在工作單元內一次刪除所有鍵,請按照下列步驟操作:
sharedStorage.clear();
使用回應標頭
如要使用回應標頭刪除值,您也可以在回應標頭中使用
Shared-Storage-Write
,傳遞要刪除的鍵。delete;key="myKey"
如要使用回應標頭刪除所有鍵,請按照下列步驟操作:
clear;
從共用儲存空間讀取 Protected Audience 興趣群組
您可以透過共用儲存空間工作區讀取 Protected Audience 的興趣群組。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);
}
載入工作區模組的瀏覽內容來源會決定預設讀取的興趣群組來源。如要進一步瞭解預設工作區來源和變更方式,請參閱「執行 Shared Storage 和 Private Aggregation」一節,瞭解 Shared Storage API 操作說明。
選項
所有 Shared Storage 修飾符方法都支援選用的選項物件做為最後一個引數。
withLock
withLock
選項為選用項目。如果指定此選項,方法會先使用 Web Locks API 取得定義資源的鎖定,再繼續執行。要求鎖定時會傳遞鎖定名稱。這個名稱代表資源,其用途是在來源中跨多個分頁、工作站或程式碼進行協調。
withLock
選項可與下列 Shared Storage 輔助鍵方法搭配使用:
- set
- 附加
- 刪除
- 關閉
- 批次更新
您可以使用 JavaScript 或回應標頭設定鎖定:
使用 JavaScript
sharedStorage.set('myKey', 'myValue', { withLock: 'myResource' });
使用回應標頭
Shared-Storage-Write : set;key="myKey";value="myValue";with_lock="myResource"
共用儲存空間鎖定功能會依資料來源區分。鎖定與使用 LockManager request() 方法取得的任何鎖定無關,無論是在 window
或 worker
上下文中皆然。不過,它們與 SharedStorageWorklet 情境中使用 request()
取得的鎖定項目共用相同範圍。
雖然 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
範例會使用 modify-lock
為 keyOne
和 keyTwo
設定新值,然後執行工作區中的 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()
時,系統會將資料寫入嵌入者的 Shared Storage。當您在 iframe 中載入第三方程式碼時,程式碼會收到新的瀏覽內容,其來源為 iframe 的來源。因此,從 iframe 發出的 sharedStorage.set()
呼叫會將資料儲存至 iframe 來源的 Shared Storage。
第一方情境
如果第一方網頁內嵌呼叫 sharedStorage.set()
或 sharedStorage.delete()
的第三方 JavaScript 程式碼,則鍵/值組合會儲存在第一方內容中。

第三方情境
您可以建立 iframe,並在 iframe 內的 JavaScript 程式碼中呼叫 set()
或 delete()
,將鍵/值組合儲存在廣告技術或第三方內容中。

私密匯總 API
如要評估儲存在 Shared Storage 中的可匯總資料,您可以使用 Private Aggregation API。
如要建立報表,請在工作區塊中使用值和值區呼叫 contributeToHistogram()
。這個區塊會以不帶正負號的 128 位元整數表示,且必須以 BigInt
的形式傳遞至函式。值為正整數。
為保護隱私權,報表的酬載 (包含資料集和值) 會在傳輸期間加密,且只能使用匯總服務解密及匯總。
瀏覽器也會限制網站對輸出查詢的貢獻。具體來說,貢獻預算會限制單一網站在特定時間範圍內,針對特定瀏覽器的所有報表總和,並涵蓋所有分類。如果超過目前預算,系統就不會產生報表。
privateAggregation.contributeToHistogram({
bucket: BigInt(myBucket),
value: parseInt(myBucketValue)
});
執行 Shared Storage 和 Private Aggregation
您必須建立工作物件,才能存取共用儲存空間中的資料。為此,請使用工作區的網址呼叫 createWorklet()
。根據預設,當您使用 createWorklet()
搭配共用儲存空間時,資料分割區來源會是叫用的瀏覽內容來源,而不是工作區範本本身的來源。
如要變更預設行為,請在呼叫 createWorklet
時設定 dataOrigin
屬性。
dataOrigin: "context-origin"
:(預設) 資料會儲存在叫用瀏覽內容來源的共用儲存空間中。dataOrigin: "script-origin"
:資料會儲存在工作區塊指令碼來源的共用儲存空間中。請注意,您必須選擇採用,才能啟用這個模式。
sharedStorage.createWorklet(scriptUrl, {dataOrigin: "script-origin"});
如要選擇加入,請在使用 "script-origin"
時,指令碼端點必須回應標頭 Shared-Storage-Cross-Origin-Worklet-Allowed
。請注意,應為跨來源要求啟用 CORS。
Shared-Storage-Cross-Origin-Worklet-Allowed : ?1
使用跨來源 iframe
您需要使用 iframe 才能叫用共用儲存空間小程式。
在廣告的 iframe 中,呼叫 addModule()
以載入 worklet 模組。如要在同一個廣告 iframe JavaScript 中,執行 sharedStorageWorklet.js
工作區塊檔案中註冊的方法,請呼叫 sharedStorage.run()
。
const sharedStorageWorklet = await window.sharedStorage.createWorklet(
'https://any-origin.example/modules/sharedStorageWorklet.js'
);
await sharedStorageWorklet.run('shared-storage-report', {
data: { campaignId: '1234' },
});
在 worklet 指令碼中,您需要使用非同步 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);
使用跨來源要求
共用儲存空間和私人匯總可讓您建立跨來源的 worklet,而不需要跨來源 iframe。
第一方網頁也可以對跨來源 JavaScript 端點叫用 createWorklet()
。建立工作區時,您需要將工作區的資料區隔來源設為指向指令碼來源。
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
});
}
}
後續步驟
以下頁面將說明 Shared Storage API 和 Private Aggregation API 的重要面向。
- 共用儲存空間簡介 (Chrome 開發人員版)
- 共用儲存空間用途 (Chrome 開發人員版)
- 私人匯總功能簡介 (Chrome 開發人員版)
- Shared Storage Explainer (GitHub)
- 私人匯總說明 (GitHub)
- 共用儲存空間和 Private Aggregation 示範
熟悉 API 後,您就可以開始收集報表,這些報表會以 POST 要求傳送至下列端點,並在要求主體中以 JSON 格式傳送。
- 偵錯報表 -
context-origin/.well-known/private-aggregation/debug/report-shared-storage
- 報表 -
context-origin/.well-known/private-aggregation/report-shared-storage
收集報表後,您可以使用本機測試工具進行測試,或設定匯總服務的受信任執行環境,以便取得匯總報表。
提供意見
歡迎在 GitHub 上分享您對 API 和說明文件的意見。