Chrome จะเริ่มช่วงทดลองใช้จากต้นทางสำหรับการเพิ่มส่วนหัว HTTP ไปยัง Storage Access API (SAA) ในเวอร์ชัน 130 ซึ่งก็คือ Storage Access Headers Sec-Fetch-Storage-Accessส่วนหัวของคำขอและActivate-Storage-Accessส่วนหัวของการตอบกลับใหม่มีจุดประสงค์เพื่อรองรับทรัพยากรที่ไม่ใช่ iframe รวมถึงปรับปรุงประสิทธิภาพและประสบการณ์ของผู้ใช้สำหรับเว็บไซต์ที่ใช้เนื้อหาที่ฝัง เช่น วิดเจ็ตโซเชียลมีเดีย ปฏิทิน และเครื่องมือแบบอินเทอร์แอกทีฟ
โฟลว์ JavaScript (และข้อจำกัด)
ก่อนหน้านี้ SAA กำหนดให้ต้องมีการเรียกใช้ JavaScript API เพื่อ document.requestStorageAccess() ทุกครั้งที่โหลดซ้ำ แม้ว่าผู้ใช้จะให้สิทธิ์แล้วก็ตาม แม้ว่าวิธีนี้จะมีประสิทธิภาพ แต่ก็มีข้อจำกัดดังนี้
- การเดินทางไปกลับของเครือข่ายหลายครั้ง: กระบวนการนี้มักเกี่ยวข้องกับคำขอเครือข่ายและการโหลดหน้าเว็บซ้ำหลายครั้งก่อนที่เนื้อหาที่ฝังจะทำงานได้อย่างเต็มที่
- การขึ้นอยู่กับ iframe: การเรียกใช้ JavaScript กำหนดให้ใช้ iframe หรือทรัพยากรย่อยภายใน iframe ซึ่งจำกัดความยืดหยุ่นสำหรับนักพัฒนาซอฟต์แวร์
เช่น วิดเจ็ตปฏิทินจาก calendar.example ที่ฝังไว้ใน website.example โดยใช้ JavaScript เพียงอย่างเดียวจะมีลักษณะดังนี้
- โหลดตัวยึดตำแหน่ง:
website.exampleจะส่งคำขอวิดเจ็ต เนื่องจากcalendar.exampleวิดเจ็ตที่ฝังอยู่ในwebsite.exampleไม่มีสิทธิ์เข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชันของตัวเอง ระบบจึงแสดงผลวิดเจ็ตตัวยึดตำแหน่งแทน - ขอสิทธิ์: ตัวยึดตำแหน่งจะโหลด จากนั้นเรียกใช้
document.requestStorageAccess()เพื่อขอสิทธิ์storage-access - ผู้ใช้เลือกให้สิทธิ์
- โหลดวิดเจ็ตซ้ำ: วิดเจ็ตจะรีเฟรช โดยครั้งนี้จะมีการเข้าถึงคุกกี้ และโหลดเนื้อหาที่ปรับเปลี่ยนในแบบของคุณในที่สุด
- ทุกครั้งที่ผู้ใช้เข้าชมเว็บไซต์ที่ฝังวิดเจ็ต
calendar.exampleอีกครั้ง ขั้นตอนจะเหมือนกับขั้นตอนที่ 1, 2 และ 4 ทุกประการ โดยความแตกต่างเพียงอย่างเดียวคือผู้ใช้ไม่จำเป็นต้องให้สิทธิ์เข้าถึงอีกครั้ง
โฟลว์นี้ไม่มีประสิทธิภาพ หากผู้ใช้ให้สิทธิ์เข้าถึงพื้นที่เก็บข้อมูลแล้ว การโหลด iframe เริ่มต้น การเรียกใช้ document.requestStorageAccess() และการโหลดซ้ำในภายหลังก็ไม่จำเป็นและทำให้เกิดเวลาในการตอบสนอง
ขั้นตอนใหม่ที่มีส่วนหัว HTTP
ส่วนหัว Storage Access ใหม่ช่วยให้โหลดเนื้อหาที่ฝังไว้ได้อย่างมีประสิทธิภาพมากขึ้น รวมถึงทรัพยากรที่ไม่ใช่ iframe
เมื่อมีส่วนหัว Storage Access เบราว์เซอร์จะดึงข้อมูลทรัพยากรโดยอัตโนมัติโดยตั้งค่าส่วนหัวของคำขอ Sec-Fetch-Storage-Access: inactive หากผู้ใช้ให้สิทธิ์แล้ว นักพัฒนาแอปไม่ต้องดำเนินการใดๆ เพื่อตั้งค่าส่วนหัวของคำขอ เซิร์ฟเวอร์สามารถตอบกลับด้วยส่วนหัว Activate-Storage-Access: retry; allowed-origin="<origin>" และเบราว์เซอร์จะลองส่งคำขออีกครั้งโดยใช้ข้อมูลเข้าสู่ระบบที่จำเป็น
ส่วนหัวของคำขอ
Sec-Fetch-Storage-Access: <access-status>
เมื่อผู้ใช้เข้าชมหน้าที่ฝังเนื้อหาข้ามเว็บไซต์ เบราว์เซอร์จะรวมส่วนหัว Sec-Fetch-Storage-Access ไว้ในคำขอข้ามเว็บไซต์โดยอัตโนมัติ ซึ่งอาจต้องใช้ข้อมูลเข้าสู่ระบบ (เช่น คุกกี้) ส่วนหัวนี้ระบุสถานะสิทธิ์เข้าถึงคุกกี้ของฝัง วิธีตีความค่ามีดังนี้
none: การฝังไม่มีสิทธิ์storage-accessจึงไม่มีสิทธิ์เข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชันinactive: วิดีโอที่ฝังมีสิทธิ์storage-accessแต่ไม่ได้เลือกใช้ การฝังไม่มีสิทธิ์เข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชันactive: การฝังมีการเข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชัน ค่านี้จะรวมอยู่ในคำขอข้ามต้นทางใดๆ ที่มีสิทธิ์เข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชัน
ส่วนหัวการตอบกลับ
Activate-Storage-Access: <retry-or-reload>
ส่วนหัว Activate-Storage-Access จะสั่งให้เบราว์เซอร์ลองส่งคำขออีกครั้งโดยใช้คุกกี้ หรือโหลดทรัพยากรโดยตรงเมื่อเปิดใช้งาน SAA ส่วนหัวอาจมีค่าดังต่อไปนี้
load: สั่งให้เบราว์เซอร์ให้สิทธิ์เข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชันแก่ผู้ฝังสำหรับทรัพยากรที่ขอretry: เซิร์ฟเวอร์ตอบกลับว่าเบราว์เซอร์ควรเปิดใช้งานสิทธิ์เข้าถึงพื้นที่เก็บข้อมูล แล้วลองส่งคำขออีกครั้ง
Activate-Storage-Access: retry; allowed-origin="https://site.example"
Activate-Storage-Access: retry; allowed-origin=*
Activate-Storage-Access: load
การรองรับทรัพยากรที่ไม่ใช่ iframe
การอัปเดตส่วนหัวการเข้าถึงพื้นที่เก็บข้อมูลจะเปิดใช้ SAA สำหรับเนื้อหาที่ฝังที่ไม่ใช่ iframe เช่น รูปภาพที่โฮสต์ในโดเมนอื่น ก่อนหน้านี้ไม่มี Web Platform API ใดที่อนุญาตให้โหลดทรัพยากรดังกล่าวด้วยข้อมูลเข้าสู่ระบบในเบราว์เซอร์หากไม่มีคุกกี้ของบุคคลที่สาม
เช่น embedding-site.example สามารถขอรูปภาพได้โดย
<img src="https://server.example/image"/>
และเซิร์ฟเวอร์จะตอบกลับด้วยเนื้อหาหรือข้อผิดพลาด ทั้งนี้ขึ้นอยู่กับว่ามีคุกกี้หรือไม่
app.get('/image', (req, res) => {
const headers = req.headers;
const cookieHeader = headers.cookie;
// Check if the embed has the necessary cookie access
if (!cookieHeader || !cookieHeader.includes('foo')) {
// If the cookie is not present, check if the browser supports Storage Access headers
if (
'sec-fetch-storage-access' in headers &&
headers['sec-fetch-storage-access'] == 'inactive'
) {
// If the browser supports Storage Access API, retry the request with storage access enabled
res.setHeader('Activate-Storage-Access', 'retry; allowed-origin="https://embedding-site.example"');
}
res.status(401).send('No cookie!');
} else {
// If the cookie is available, check if the user is authorized to access the image
if (!check_authorization(cookieHeader)) {
return res.status(401).send('Unauthorized!');
}
// If the user is authorized, respond with the image file
res.sendFile("path/to/image.jpeg");
}
});
หากไม่มีคุกกี้ เซิร์ฟเวอร์จะตรวจสอบค่าของส่วนหัวคำขอ Sec-Fetch-Storage-Access หากตั้งค่านี้เป็น inactive เซิร์ฟเวอร์จะตอบกลับด้วยส่วนหัว Activate-Storage-Access: retry ซึ่งบ่งชี้ว่าควรลองส่งคำขออีกครั้งโดยมีการเข้าถึงพื้นที่เก็บข้อมูล หากไม่มีคุกกี้และส่วนหัว Sec-Fetch-Storage-Access ไม่มีค่าเป็น "ไม่ใช้งาน" รูปภาพจะไม่โหลด
โฟลว์ส่วนหัว HTTP
ส่วนหัว HTTP ช่วยให้เบราว์เซอร์ทราบได้ว่าเมื่อใดที่ผู้ใช้ได้ให้สิทธิ์เข้าถึงพื้นที่เก็บข้อมูลแก่วิดเจ็ตแล้ว และโหลด iframe ที่มีสิทธิ์เข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชันในครั้งต่อๆ ไป
เมื่อใช้ส่วนหัว Storage Access การเข้าชมหน้าเว็บในภายหลังจะทริกเกอร์โฟลว์ต่อไปนี้
- ผู้ใช้เข้าชม
website.exampleที่ฝังcalendar.exampleอีกครั้ง การดึงข้อมูลนี้ยังไม่มีสิทธิ์เข้าถึงคุกกี้เหมือนเดิม อย่างไรก็ตาม ผู้ใช้ได้ให้สิทธิ์storage-accessไว้ก่อนหน้านี้แล้ว และการดึงข้อมูลมีส่วนหัวSec-Fetch-Storage-Access: inactiveเพื่อระบุว่ามีการเข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชัน แต่ไม่ได้ใช้งาน - เซิร์ฟเวอร์
calendar.exampleตอบกลับด้วยส่วนหัวActivate-Storage-Access: retry; allowed-origin="<origin>"(ในกรณีนี้<origin>จะเป็นhttps://website.example) เพื่อระบุว่าการดึงข้อมูลทรัพยากรต้องใช้คุกกี้ที่ไม่ได้แบ่งพาร์ติชันที่มีสิทธิ์เข้าถึงพื้นที่เก็บข้อมูล - เบราว์เซอร์จะลองส่งคำขออีกครั้ง โดยครั้งนี้จะรวมคุกกี้ที่ไม่ได้แบ่งพาร์ติชัน (เปิดใช้งานสิทธิ์
storage-accessสำหรับการดึงข้อมูลนี้) calendar.exampleเซิร์ฟเวอร์จะตอบกลับด้วยเนื้อหา iframe ที่ปรับเปลี่ยนในแบบของคุณ การตอบกลับมีส่วนหัวActivate-Storage-Access: loadเพื่อระบุว่าเบราว์เซอร์ควรโหลดเนื้อหาโดยเปิดใช้งานสิทธิ์storage-access(กล่าวคือ โหลดโดยมีการเข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชัน เหมือนกับว่ามีการเรียกใช้document.requestStorageAccess())- User Agent จะโหลดเนื้อหา iframe โดยมีการเข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชันโดยใช้สิทธิ์การเข้าถึงพื้นที่เก็บข้อมูล หลังจากขั้นตอนนี้ วิดเจ็ตจะทำงานได้ตามที่คาดไว้
อัปเดตโซลูชัน
เมื่อใช้ฟีเจอร์ Storage Access Headers คุณอาจต้องอัปเดตโค้ดใน 2 กรณีต่อไปนี้
- คุณใช้ SAA และต้องการให้ได้ประสิทธิภาพที่ดีขึ้นด้วยตรรกะส่วนหัว
- คุณมีการตรวจสอบหรือตรรกะที่ขึ้นอยู่กับว่าส่วนหัว
Originรวมอยู่ในคำขอในเซิร์ฟเวอร์หรือไม่
ใช้ตรรกะส่วนหัวของ SAA
หากต้องการใช้ Storage Access Headers ในโซลูชัน คุณจะต้องอัปเดตโซลูชัน สมมติว่าคุณเป็นcalendar.exampleเจ้าของ หากต้องการให้ website.example โหลดวิดเจ็ต calendar.example ที่ปรับเปลี่ยนในแบบของคุณได้ โค้ดวิดเจ็ตต้องมีสิทธิ์เข้าถึงพื้นที่เก็บข้อมูล
ฝั่งไคลเอ็นต์
ฟีเจอร์ Storage Access Headers ไม่จำเป็นต้องมีการอัปเดตโค้ดฝั่งไคลเอ็นต์สำหรับโซลูชันที่มีอยู่ อ่านเอกสารประกอบเพื่อดูวิธีใช้ SAA
ฝั่งเซิร์ฟเวอร์
ในฝั่งเซิร์ฟเวอร์ คุณสามารถใช้ส่วนหัวใหม่ได้ดังนี้
app.get('/cookie-access-endpoint', (req, res) => {
const storageAccessHeader = req.headers['sec-fetch-storage-access'];
if (storageAccessHeader === 'inactive') {
// User needs to grant permission, trigger a prompt
if (!validate_origin(req.headers.origin)) {
res.status(401).send(`${req.headers.origin} is not allowed to send` +
' credentialed requests to this server.');
return;
}
res.set('Activate-Storage-Access', `retry; allowed-origin="${req.headers.origin}"`);
res.status(401).send('This resource requires storage access. Please grant permission.');
} else if (storageAccessHeader === 'active') {
// User has granted permission, proceed with access
res.set('Activate-Storage-Access', 'load');
// Include the actual iframe content here
res.send('This is the content that requires cookie access.');
} else {
// Handle other cases (e.g., 'Sec-Fetch-Storage-Access': 'none')
}
});
ดูการสาธิตเพื่อดูว่าโซลูชันนี้ทำงานอย่างไรในทางปฏิบัติ
อัปเดตตรรกะของส่วนหัว Origin
เมื่อใช้ส่วนหัวการเข้าถึงพื้นที่เก็บข้อมูล Chrome จะส่งส่วนหัว Origin ในคำขอมากขึ้นกว่าเดิม ซึ่งอาจส่งผลต่อตรรกะฝั่งเซิร์ฟเวอร์หากตรรกะดังกล่าวอาศัยส่วนหัว Origin ที่มีอยู่เฉพาะสำหรับคำขอบางประเภท (เช่น คำขอที่กำหนดโดย CORS)
คุณต้องตรวจสอบโค้ดฝั่งเซิร์ฟเวอร์เพื่อหลีกเลี่ยงปัญหาที่อาจเกิดขึ้น โดยทำดังนี้
- ตรวจสอบการตรวจสอบหรือตรรกะที่ขึ้นอยู่กับการมีส่วนหัว
Origin - อัปเดตโค้ดเพื่อจัดการกับส่วนหัว
Originในกรณีต่างๆ มากขึ้น
ข้อดีหลัก
ส่วนหัว Storage Access เป็นวิธีที่แนะนําและมีประสิทธิภาพมากกว่าในการใช้ SAA โดยรวมแล้ว การเปลี่ยนแปลงนี้จะช่วยปรับปรุงสิ่งต่างๆ ดังนี้
- รองรับการฝังที่ไม่ใช่ iframe: เปิดใช้ SAA สำหรับทรัพยากรที่หลากหลายมากขึ้น
- ลดการใช้เครือข่าย: คำขอน้อยลงและเพย์โหลดเล็กลง
- การใช้งาน CPU น้อยลง: การประมวลผล JavaScript น้อยลง
- ปรับปรุงประสบการณ์ของผู้ใช้: ลดการโหลดระดับกลางที่รบกวน
เข้าร่วมการทดลองใช้จากต้นทาง
ช่วงทดลองใช้จากต้นทางช่วยให้คุณได้ลองใช้ฟีเจอร์ใหม่ๆ และแสดงความคิดเห็นเกี่ยวกับความสามารถในการใช้งาน ความสะดวก และประสิทธิภาพของฟีเจอร์เหล่านั้น ดูข้อมูลเพิ่มเติมได้ที่เริ่มต้นใช้งานการทดลองใช้ฟีเจอร์ต้นทาง
คุณลองใช้ฟีเจอร์ Storage Access Headers ได้โดยลงทะเบียนเข้าร่วมช่วงทดลองใช้จากต้นทางซึ่งจะเริ่มตั้งแต่ Chrome 130 เป็นต้นไป วิธีเข้าร่วมการทดลองใช้จากต้นทาง
- ไปที่หน้าลงทะเบียนช่วงทดลองใช้ Storage Access Headers จากต้นทาง
- ทำตามวิธีการเกี่ยวกับการเข้าร่วมช่วงทดลองใช้ Origin
ทดสอบในเครื่อง
คุณสามารถทดสอบฟีเจอร์ส่วนหัวของ Storage Access ในเครื่องเพื่อให้แน่ใจว่าเว็บไซต์พร้อมรับการเปลี่ยนแปลงนี้
ทำตามขั้นตอนต่อไปนี้เพื่อกำหนดค่าอินสแตนซ์ Chrome
- เปิดใช้ Chrome Flag ใน
chrome://flags/#storage-access-headers - รีสตาร์ท Chrome เพื่อให้การเปลี่ยนแปลงมีผล
มีส่วนร่วมและแชร์ความคิดเห็น
หากมีข้อเสนอแนะหรือพบปัญหา โปรดแจ้งปัญหา นอกจากนี้ คุณยังดูข้อมูลเพิ่มเติมเกี่ยวกับส่วนหัวการเข้าถึงพื้นที่เก็บข้อมูลได้ในคำอธิบายใน GitHub