กลยุทธ์ในการย้ายข้อมูลเว็บไซต์จากการใช้สตริง User Agent ไปใช้คำแนะนำสำหรับไคลเอ็นต์ User Agent ใหม่
สตริง User-Agent เป็นแพลตฟอร์มการพิมพ์ลายนิ้วมือแบบพาสซีฟที่สำคัญในเบราว์เซอร์ ทั้งยังประมวลผลได้ยาก อย่างไรก็ตาม การเก็บรวบรวมและประมวลผลข้อมูล User Agent มีเหตุผลที่ถูกต้องอยู่หลายประการ สิ่งที่จําเป็นคือเส้นทางที่นําไปสู่วิธีแก้ปัญหาที่ดีกว่า คำแนะนำไคลเอ็นต์ User Agent มีทั้งวิธีอย่างชัดเจนในการประกาศความต้องการข้อมูล User Agent และวิธีการแสดงผลข้อมูลในรูปแบบที่ใช้งานง่าย
บทความนี้จะอธิบายขั้นตอนการตรวจสอบสิทธิ์เข้าถึงข้อมูล User Agent และย้ายข้อมูลการใช้สตริง User Agent ไปยังคําแนะนําสําหรับไคลเอ็นต์ User Agent
ตรวจสอบการเก็บรวบรวมและใช้ข้อมูล User Agent
คุณควรเข้าใจเหตุผลที่รวบรวมข้อมูลอยู่เสมอ เช่นเดียวกับการเก็บรวบรวมข้อมูลในรูปแบบอื่นๆ ขั้นตอนแรกไม่ว่าคุณจะดําเนินการหรือไม่ก็ตามคือทําความเข้าใจตําแหน่งและเหตุผลที่คุณใช้ข้อมูล User Agent
หากไม่ทราบว่าระบบใช้ข้อมูล User-agent หรือไม่และที่ใด ให้ลองค้นหาโค้ดฝั่งหน้าเว็บเพื่อหาการใช้ navigator.userAgent
และโค้ดฝั่งหลังเพื่อหาการใช้ส่วนหัว HTTP ของ User-Agent
นอกจากนี้ คุณควรตรวจสอบโค้ดฝั่งหน้าเว็บเพื่อหาการใช้ฟีเจอร์ที่เลิกใช้งานแล้ว เช่น navigator.platform
และ navigator.appVersion
จากมุมมองฟังก์ชัน ให้นึกถึงทุกจุดในโค้ดที่คุณบันทึกหรือประมวลผลข้อมูล
- ชื่อหรือเวอร์ชันของเบราว์เซอร์
- ชื่อหรือเวอร์ชันของระบบปฏิบัติการ
- ยี่ห้อหรือรุ่นของอุปกรณ์
- ประเภท สถาปัตยกรรม หรือจำนวนบิตของ CPU (เช่น 64 บิต)
นอกจากนี้ คุณอาจใช้ไลบรารีหรือบริการของบุคคลที่สามเพื่อประมวลผล User Agent ด้วย ในกรณีนี้ ให้ตรวจสอบว่ามีการอัปเดตเพื่อรองรับคำแนะนำสำหรับไคลเอ็นต์ของ User Agent หรือไม่
คุณใช้เฉพาะข้อมูล User Agent พื้นฐานหรือไม่
ชุดคําแนะนําสําหรับไคลเอ็นต์ User Agent เริ่มต้นมีดังนี้
Sec-CH-UA
: ชื่อเบราว์เซอร์และเวอร์ชันหลัก/สำคัญSec-CH-UA-Mobile
: ค่าบูลีนที่ระบุอุปกรณ์เคลื่อนที่Sec-CH-UA-Platform
: ชื่อระบบปฏิบัติการ- โปรดทราบว่าข้อมูลนี้ได้รับการอัปเดตในข้อกำหนดและจะแสดงใน Chrome และเบราว์เซอร์อื่นๆ ที่พัฒนาบน Chromium ในไม่ช้า
สตริง User Agent เวอร์ชันที่ลดลงซึ่งเราเสนอจะเก็บข้อมูลพื้นฐานนี้ไว้ด้วยในลักษณะที่เข้ากันได้แบบย้อนหลัง เช่น แทนที่จะเป็น Chrome/90.0.4430.85
สตริงจะมี Chrome/90.0.0.0
หากคุณตรวจสอบเฉพาะสตริง User-Agent สําหรับชื่อเบราว์เซอร์ เวอร์ชันหลัก หรือระบบปฏิบัติการ โค้ดจะยังคงทํางานต่อไปแม้ว่าคุณอาจเห็นคําเตือนการเลิกใช้งาน
แม้ว่าคุณจะย้ายข้อมูลไปยังคำแนะนำสำหรับไคลเอ็นต์ของ User Agent ได้และควรย้าย แต่คุณอาจมีโค้ดเดิมหรือข้อจำกัดด้านทรัพยากรที่ทําให้ดำเนินการนี้ไม่ได้ การลดข้อมูลในสตริง User Agent ด้วยวิธีที่เข้ากันได้แบบย้อนหลังนี้มีจุดประสงค์เพื่อให้มั่นใจว่าแม้โค้ดที่มีอยู่จะได้รับข้อมูลที่ละเอียดน้อยลง แต่ก็ยังควรรักษาฟังก์ชันพื้นฐานไว้
กลยุทธ์: JavaScript API ฝั่งไคลเอ็นต์แบบออนดีมานด์
หากใช้ navigator.userAgent
อยู่ในปัจจุบัน คุณควรเปลี่ยนไปใช้ navigator.userAgentData
ก่อนกลับไปใช้การแยกวิเคราะห์สตริง user-agent
if (navigator.userAgentData) {
// use new hints
} else {
// fall back to user-agent string parsing
}
หากคุณกำลังตรวจสอบอุปกรณ์เคลื่อนที่หรือเดสก์ท็อป ให้ใช้ค่าบูลีน mobile
ดังนี้
const isMobile = navigator.userAgentData.mobile;
userAgentData.brands
คืออาร์เรย์ของออบเจ็กต์ที่มีพร็อพเพอร์ตี้ brand
และ version
ซึ่งเบราว์เซอร์จะแสดงรายการความเข้ากันได้กับแบรนด์เหล่านั้น คุณสามารถเข้าถึงข้อมูลดังกล่าวโดยตรงในรูปแบบอาร์เรย์ หรืออาจใช้การเรียก some()
เพื่อตรวจสอบว่ามีรายการที่เฉพาะเจาะจงหรือไม่
function isCompatible(item) {
// In real life you most likely have more complex rules here
return ['Chromium', 'Google Chrome', 'NewBrowser'].includes(item.brand);
}
if (navigator.userAgentData.brands.some(isCompatible)) {
// browser reports as compatible
}
หากต้องการค่า User Agent ที่ละเอียดยิ่งขึ้นและมีข้อมูลเชิงตัวเลขสูง คุณจะต้องระบุค่าดังกล่าวและตรวจสอบผลลัพธ์ใน Promise
ที่แสดงผล
navigator.userAgentData.getHighEntropyValues(['model'])
.then(ua => {
// requested hints available as attributes
const model = ua.model
});
นอกจากนี้ คุณอาจต้องใช้กลยุทธ์นี้หากต้องการเปลี่ยนจากการประมวลผลฝั่งเซิร์ฟเวอร์เป็นการประมวลผลฝั่งไคลเอ็นต์ JavaScript API ไม่จำเป็นต้องเข้าถึงส่วนหัวคำขอ HTTP คุณจึงขอค่า User Agent ได้ทุกเมื่อ
กลยุทธ์: ส่วนหัวฝั่งเซิร์ฟเวอร์แบบคงที่
หากคุณใช้ส่วนหัวคำขอ User-Agent
ในเซิร์ฟเวอร์และความต้องการข้อมูลนั้นค่อนข้างสอดคล้องกันทั่วทั้งเว็บไซต์ คุณสามารถระบุคำแนะนำไคลเอ็นต์ที่ต้องการเป็นชุดแบบคงที่ในการตอบกลับ วิธีนี้เป็นวิธีที่ค่อนข้างง่าย เนื่องจากโดยทั่วไปคุณจะต้องกําหนดค่าในตำแหน่งเดียวเท่านั้น เช่น อาจเป็นการกำหนดค่าเว็บเซิร์ฟเวอร์หากคุณเพิ่มส่วนหัวไว้แล้ว การกำหนดค่าโฮสติ้ง หรือการกำหนดค่าระดับบนสุดของเฟรมเวิร์กหรือแพลตฟอร์มที่คุณใช้สำหรับเว็บไซต์
ลองใช้กลยุทธ์นี้หากคุณกำลังเปลี่ยนรูปแบบหรือปรับแต่งคำตอบที่แสดงตามข้อมูล User Agent
เนื่องจากเบราว์เซอร์หรือไคลเอ็นต์อื่นๆ อาจเลือกให้คำแนะนำเริ่มต้นที่แตกต่างกัน คุณจึงควรระบุทุกอย่างที่ต้องการ แม้ว่าโดยทั่วไปแล้วจะมีให้โดยค่าเริ่มต้นก็ตาม
เช่น ค่าเริ่มต้นปัจจุบันของ Chrome จะแสดงเป็น
⬇️ ส่วนหัวการตอบกลับ
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA
หากต้องการรับรุ่นอุปกรณ์ในการตอบกลับด้วย ให้ส่งข้อมูลต่อไปนี้
⬇️ ส่วนหัวการตอบกลับ
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platform, Sec-CH-UA
เมื่อประมวลผลข้อมูลนี้ฝั่งเซิร์ฟเวอร์ คุณควรตรวจสอบก่อนว่ามีการส่งส่วนหัว Sec-CH-UA
ที่ต้องการหรือไม่ จากนั้นจึงเปลี่ยนไปใช้การแยกวิเคราะห์ส่วนหัว User-Agent
หากไม่พร้อมใช้งาน
กลยุทธ์: การมอบหมายคำแนะนำให้กับคำขอข้ามต้นทาง
หากคุณขอทรัพยากรย่อยข้ามแหล่งที่มาหรือข้ามเว็บไซต์ที่กําหนดให้ส่งคําแนะนําสําหรับไคลเอ็นต์ของ User Agent ในคําขอ คุณจะต้องระบุคําแนะนําที่ต้องการอย่างชัดเจนโดยใช้นโยบายสิทธิ์
ตัวอย่างเช่น สมมติว่า https://blog.site
โฮสต์ทรัพยากรใน https://cdn.site
ซึ่งสามารถแสดงผลทรัพยากรที่เพิ่มประสิทธิภาพสำหรับอุปกรณ์หนึ่งๆ ได้
https://blog.site
ขอคำแนะนำ Sec-CH-UA-Model
ได้ แต่ต้องมอบหมายให้ https://cdn.site
อย่างชัดเจนโดยใช้ส่วนหัว Permissions-Policy
รายการคำแนะนำที่ควบคุมโดยนโยบายมีอยู่ในโครงสร้างพื้นฐาน Client Hints
⬇️ การตอบกลับจาก blog.site
ที่มอบหมายคำใบ้
Accept-CH: Sec-CH-UA-Model
Permissions-Policy: ch-ua-model=(self "https://cdn.site")
⬆️ คำขอไปยังทรัพยากรย่อยใน cdn.site
มีคำแนะนำที่มอบสิทธิ์
Sec-CH-UA-Model: "Pixel 5"
คุณสามารถระบุคำแนะนำหลายรายการสำหรับต้นทางหลายรายการได้ โดยไม่จำเป็นต้องมาจากช่วง ch-ua
เท่านั้น
⬇️ การตอบกลับจาก blog.site
ที่มอบหมายคำแนะนำหลายรายการให้กับต้นทางหลายรายการ
Accept-CH: Sec-CH-UA-Model, DPR
Permissions-Policy: ch-ua-model=(self "https://cdn.site"),
ch-dpr=(self "https://cdn.site" "https://img.site")
กลยุทธ์: การมอบหมายคำแนะนำไปยัง iframe
iframe ข้ามแหล่งที่มาทํางานคล้ายกับทรัพยากรข้ามแหล่งที่มา แต่คุณระบุคำแนะนำที่ต้องการมอบสิทธิ์ได้ในแอตทริบิวต์ allow
⬇️ การตอบกลับจาก blog.site
Accept-CH: Sec-CH-UA-Model
↪️ HTML สำหรับ blog.site
<iframe src="https://widget.site" allow="ch-ua-model"></iframe>
⬆️ ส่งคำขอไปยัง widget.site
Sec-CH-UA-Model: "Pixel 5"
แอตทริบิวต์ allow
ใน iframe จะลบล้างส่วนหัว Accept-CH
ที่ widget.site
อาจส่งเอง ดังนั้นโปรดตรวจสอบว่าคุณได้ระบุทุกอย่างที่เว็บไซต์ของ iframe จะต้องใช้งาน
กลยุทธ์: คำแนะนำฝั่งเซิร์ฟเวอร์แบบไดนามิก
หากมีบางส่วนในเส้นทางของผู้ใช้ที่คุณต้องการตัวเลือกคำแนะนำมากกว่าส่วนอื่นๆ ของเว็บไซต์ คุณอาจเลือกที่จะขอคำแนะนำเหล่านั้นแบบออนดีมานด์แทนที่จะแสดงแบบคงที่ทั่วทั้งเว็บไซต์ วิธีนี้จัดการได้ยากกว่า แต่คุณอาจใช้วิธีนี้ได้หากตั้งค่าส่วนหัวที่แตกต่างกันตามเส้นทางไว้แล้ว
สิ่งสำคัญที่ควรจำไว้คืออินสแตนซ์แต่ละรายการของAccept-CH
หัวข้อจะเขียนทับชุดที่มีอยู่ ดังนั้น หากคุณตั้งค่าส่วนหัวแบบไดนามิก แต่ละหน้าจะต้องขอชุดคำแนะนำที่จำเป็นทั้งหมด
เช่น คุณอาจมีส่วนในเว็บไซต์ที่ต้องการแสดงไอคอนและการควบคุมที่ตรงกับระบบปฏิบัติการของผู้ใช้ คุณอาจต้องดึงข้อมูล Sec-CH-UA-Platform-Version
เพิ่มเติมเพื่อแสดงทรัพยากรย่อยที่เหมาะสม
⬇️ ส่วนหัวการตอบกลับสำหรับ /blog
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA
⬇️ ส่วนหัวการตอบกลับสำหรับ /app
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA-Platform-Version, Sec-CH-UA
กลยุทธ์: ต้องใช้คำแนะนำฝั่งเซิร์ฟเวอร์ในคำขอแรก
อาจมีกรณีที่คุณต้องระบุคำใบ้มากกว่าชุดค่าเริ่มต้นในคำขอแรก แต่กรณีนี้เกิดขึ้นไม่บ่อยนัก ดังนั้นโปรดตรวจสอบเหตุผล
คําขอแรกหมายถึงคําขอระดับบนสุดครั้งแรกสําหรับต้นทางนั้นซึ่งส่งในเซสชันการท่องเว็บนั้น ชุดคำแนะนำเริ่มต้นประกอบด้วยชื่อเบราว์เซอร์พร้อมเวอร์ชันหลัก แพลตฟอร์ม และตัวบ่งชี้อุปกรณ์เคลื่อนที่ คำถามที่เราจะถามคือคุณต้องการข้อมูลเพิ่มเติมเกี่ยวกับการโหลดหน้าเว็บครั้งแรกไหม
คำแนะนำเพิ่มเติมสำหรับคำขอแรกมี 2 ตัวเลือก ก่อนอื่น คุณสามารถใช้ส่วนหัว Critical-CH
รูปแบบนี้เหมือนกับ Accept-CH
แต่บอกให้เบราว์เซอร์ลองส่งคำขออีกครั้งทันทีหากส่งคำขอแรกโดยไม่มีคำแนะนำที่สำคัญ
⬆️ คำขอเริ่มต้น
[With default headers]
⬇️ ส่วนหัวการตอบกลับ
Accept-CH: Sec-CH-UA-Model
Critical-CH: Sec-CH-UA-Model
🔃 เบราว์เซอร์ลองส่งคำขอเริ่มต้นอีกครั้งโดยใช้ส่วนหัวเพิ่มเติม
[With default headers + …]
Sec-CH-UA-Model: Pixel 5
วิธีนี้จะมีค่าใช้จ่ายเพิ่มเติมในการลองอีกครั้งในคำขอแรก แต่ค่าใช้จ่ายในการติดตั้งใช้งานค่อนข้างต่ำ ส่งส่วนหัวเพิ่มเติมแล้วเบราว์เซอร์จะดำเนินการที่เหลือ
สำหรับกรณีที่คุณต้องการคำแนะนำเพิ่มเติมในการโหลดหน้าเว็บครั้งแรก ข้อเสนอความน่าเชื่อถือของคำแนะนำไคลเอ็นต์จะแสดงเส้นทางในการระบุคำแนะนำในการตั้งค่าระดับการเชื่อมต่อ ซึ่งใช้ประโยชน์จากส่วนขยาย Application-Layer Protocol(ALPS) ใน TLS 1.3 เพื่อเปิดใช้การส่งคำแนะนำล่วงหน้าในการเชื่อมต่อ HTTP/2 และ HTTP/3 การดำเนินการนี้ยังอยู่ในขั้นเริ่มต้นมากๆ แต่หากคุณจัดการการตั้งค่า TLS และการเชื่อมต่อของคุณเองอยู่เสมอ ตอนนี้เป็นโอกาสที่ดีในการมีส่วนร่วม
กลยุทธ์: การรองรับเวอร์ชันเก่า
คุณอาจมีโค้ดเดิมหรือโค้ดของบุคคลที่สามในเว็บไซต์ซึ่งใช้ navigator.userAgent
รวมถึงสตริง User Agent บางส่วนที่จะลดลง ในระยะยาว คุณควรวางแผนที่จะเปลี่ยนไปใช้การเรียกใช้navigator.userAgentData
ที่เทียบเท่า แต่ก็มีวิธีแก้ปัญหาชั่วคราว
UA-CH retrofill เป็นไลบรารีขนาดเล็กที่ช่วยให้คุณเขียนทับ navigator.userAgent
ด้วยสตริงใหม่ซึ่งสร้างขึ้นจากค่า navigator.userAgentData
ที่ขอ
ตัวอย่างเช่น โค้ดนี้จะสร้างสตริง User Agent ที่มีคำแนะนำ "model" เพิ่มเติม
import { overrideUserAgentUsingClientHints } from './uach-retrofill.js';
overrideUserAgentUsingClientHints(['model'])
.then(() => { console.log(navigator.userAgent); });
สตริงที่ได้จะแสดงรูปแบบ Pixel 5
แต่ยังคงแสดง 92.0.0.0
แบบย่อเนื่องจากไม่ได้ขอคำแนะนำ uaFullVersion
Mozilla/5.0 (Linux; Android 10.0; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.0.0 Mobile Safari/537.36
การสนับสนุนเพิ่มเติม
หากกลยุทธ์เหล่านี้ไม่ครอบคลุม Use Case ของคุณ โปรดเริ่มการสนทนาใน repo ของ privacy-sandbox-dev-support แล้วเราจะหาทางแก้ปัญหาไปด้วยกัน
รูปภาพโดย Ricardo Rocha ใน Unsplash