ย้ายข้อมูลไปยังคำแนะนำของไคลเอ็นต์ User Agent

กลยุทธ์ในการย้ายข้อมูลเว็บไซต์โดยใช้สตริง 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.0.0 แทน Chrome/90.0.4430.85

หากคุณกำลังตรวจสอบเฉพาะสตริง 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 รายการคำแนะนำที่มีการควบคุมตามนโยบายมีอยู่ในฉบับร่างของคำแนะนำของไคลเอ็นต์

⬇️ คำตอบจาก 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 Settings(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 ของคุณ โปรดเริ่มพูดคุยในที่เก็บ Privacy-sandbox-dev-support เพื่อให้เราสำรวจปัญหาของคุณร่วมกัน

รูปภาพโดย Ricardo Rocha ใน Unsplash