ใช้แบบอักษรขั้นสูงกับแบบอักษรในเครื่อง

เรียนรู้วิธีที่ Local Font Access API อนุญาตให้คุณเข้าถึงแบบอักษรที่ติดตั้งในเครื่องของผู้ใช้และรับรายละเอียดระดับต่ำเกี่ยวกับแบบอักษร

แบบอักษรสำหรับเว็บที่ปลอดภัย

ถ้าคุณทำการพัฒนาเว็บมานานพอสมควรแล้ว คุณอาจจำได้ว่า แบบอักษรที่ปลอดภัยสำหรับเว็บ เป็นที่ทราบกันว่าแบบอักษรเหล่านี้สามารถใช้ได้ในเกือบทุกอินสแตนซ์ของระบบปฏิบัติการที่ใช้บ่อยที่สุด (ได้แก่ Windows, macOS, Linux ที่ใช้บ่อยที่สุด, Android และ iOS) ในช่วงต้นทศวรรษ 2000 Microsoft ยังเป็นผู้นำ โครงการริเริ่ม ที่เรียกว่าแบบอักษรหลัก TrueType สำหรับเว็บ ซึ่งให้แบบอักษรเหล่านี้สำหรับการดาวน์โหลดฟรีด้วย วัตถุประสงค์ที่ "เมื่อคุณเข้าชมเว็บไซต์ที่ระบุเว็บไซต์ คุณจะเห็นหน้าเว็บเหมือนกับ จุดประสงค์ของผู้ออกแบบเว็บไซต์" ใช่ เว็บไซต์ที่รวมนี้ซึ่งอยู่ใน Comic Sans MS ต่อไปนี้คือ ชุดแบบอักษรที่ปลอดภัยสำหรับเว็บแบบคลาสสิก (พร้อมตัวเลือกสำรองที่ดีที่สุด sans-serif font) อาจมีลักษณะดังนี้

body {
  font-family: Helvetica, Arial, sans-serif;
}

แบบอักษรเว็บ

ยุคสมัยที่แบบอักษรสำหรับความปลอดภัยของเว็บมีความสำคัญอย่างยิ่งยวดนั้นหายไปนานแล้ว วันนี้เรามี แบบอักษรเว็บ บางส่วน เช่น แม้กระทั่งแบบอักษรที่เปลี่ยนแปลงได้ เราสามารถปรับแต่งเพิ่มเติมโดยการเปลี่ยนค่าสำหรับ แกนต่างๆ ที่โผล่ออกมา คุณสามารถใช้แบบอักษรเว็บได้โดยประกาศ บล็อก @font-face ที่ส่วนต้นของ CSS ซึ่งระบุไฟล์แบบอักษรที่จะดาวน์โหลด

@font-face {
  font-family: 'FlamboyantSansSerif';
  src: url('flamboyant.woff2');
}

หลังจากนั้น คุณสามารถใช้แบบอักษรเว็บที่กำหนดเองได้ โดยการระบุ font-family ตามปกติ

body {
  font-family: 'FlamboyantSansSerif';
}

แบบอักษรในเครื่องเป็นเวกเตอร์ลายนิ้วมือ

แบบอักษรสำหรับเว็บส่วนใหญ่มาจากเว็บ แต่ที่น่าสนใจก็คือ พร็อพเพอร์ตี้ src ใน @font-face นอกเหนือจาก url() ยังยอมรับฟังก์ชัน local() ซึ่งทำให้สามารถโหลดแบบอักษรที่กำหนดเองได้ (เซอร์ไพรส์!) หากผู้ใช้มี FlamboyantSansSerif ที่ติดตั้งในระบบปฏิบัติการของตน ระบบจะใช้สำเนาในเครื่องแทน กำลังดาวน์โหลด:

@font-face {
  font-family: 'FlamboyantSansSerif';
  src: local('FlamboyantSansSerif'), url('flamboyant.woff2');
}

วิธีนี้มีกลไกสำรองที่ดีซึ่งอาจประหยัดแบนด์วิดท์ได้ บนอินเทอร์เน็ต แต่น่าเสียดายที่คนเราจะสิ่งดีๆ ไม่ได้ ปัญหาของฟังก์ชัน local() คืออาจ ถูกละเมิดด้วยการเก็บลายนิ้วมือของเบราว์เซอร์ ปรากฏว่า รายการแบบอักษรที่ผู้ใช้ติดตั้งมีรูปลักษณ์ การระบุตัวตน บริษัทจำนวนมากมีแบบอักษรองค์กรของตัวเอง ติดตั้งให้พนักงาน แล็ปท็อป ตัวอย่างเช่น Google มีแบบอักษรขององค์กรชื่อ Google Sans

วันที่ แอป macOS Font Book ที่แสดงตัวอย่างแบบอักษร Google Sans
แบบอักษร Google Sans ที่ติดตั้งในแล็ปท็อปของพนักงาน Google

ผู้โจมตีอาจพยายามหาว่าคนทำงานของบริษัทอะไรโดยการทดสอบการมีอยู่ของ แบบอักษรขององค์กรที่รู้จักจำนวนมาก เช่น Google Sans ผู้โจมตีจะพยายามแสดงข้อความ ตั้งค่าในแบบอักษรเหล่านี้บนผืนผ้าใบ และวัดรูปอักขระ ถ้ารูปอักขระตรงกับรูปร่างที่ทราบของ แบบอักษรขององค์กร ผู้โจมตีมีการ Hit หากรูปอักขระไม่ตรงกัน ผู้โจมตีจะทราบว่า มีการใช้แบบอักษรแทนที่เริ่มต้นเนื่องจากไม่ได้ติดตั้งแบบอักษรขององค์กร สำหรับรายละเอียดทั้งหมดเกี่ยวกับ สิ่งนี้และการโจมตีด้วยฟิงเกอร์ปรินต์อื่นๆ ของเบราว์เซอร์ โปรดอ่าน เอกสารแบบสำรวจโดย Laperdix และคณะ

แบบอักษรของบริษัทนั้นแตกต่างกัน แม้จะระบุเฉพาะรายการแบบอักษรที่ติดตั้งไว้ก็ตาม สถานการณ์ของ เวกเตอร์การโจมตีนี้เริ่มเลวร้ายมาก เมื่อเร็วๆ นี้ทีม WebKit ตัดสินใจแล้ว ไปจนถึง "รวมเฉพาะแบบอักษร [ในรายการแบบอักษรที่ใช้ได้] และแบบอักษรที่มาพร้อมกับชุดแบบอักษร ระบบ แต่ไม่ใช่แบบอักษรที่ผู้ใช้ติดตั้งในเครื่อง" (นี่คือบทความเกี่ยวกับการให้สิทธิ์เข้าถึง กับแบบอักษรในเครื่อง)

API การเข้าถึงแบบอักษรในเครื่อง

ช่วงต้นของบทความนี้อาจทำให้คุณอารมณ์ไม่ดี ไม่อยากจะเชื่อใจเรา อะไรเหรอ ไม่ต้องกังวล เราคิดว่าเราทำได้ และบางที ทุกอย่างจะไม่น่าสิ้นหวัง ก่อนอื่น ฉันขอตอบคำถามที่คุณอาจกำลังถามตัวเอง

ทำไมเราถึงต้องใช้ Local Font Access API เมื่อมีแบบอักษรเว็บด้วย

สำหรับการออกแบบและกราฟิกคุณภาพระดับมืออาชีพนั้น เป็นเรื่องยากมากที่จะส่งมอบใน ข้อมูลเว็บ อุปสรรคอย่างหนึ่งคือ ไม่สามารถเข้าถึงและใช้สิ่งต่างๆ ได้อย่างเต็มที่ ที่สร้างขึ้นและแนะนำแบบอักษรที่นักออกแบบติดตั้งไว้ในเครื่อง แบบอักษรเว็บช่วยให้เผยแพร่บางอย่างได้ Use Case แต่ไม่อาจเปิดใช้การเข้าถึงแบบเป็นโปรแกรมไปยังรูปร่างเวกเตอร์และตารางแบบอักษรที่ใช้โดย โปรแกรมแรสเตอร์เพื่อแสดงเส้นโครงร่างรูปอักขระ และเช่นเดียวกัน ก็ไม่สามารถเข้าถึงไบนารีของแบบอักษรเว็บได้

  • เครื่องมือออกแบบต้องมีสิทธิ์เข้าถึงไบต์ของแบบอักษรเพื่อทำการติดตั้งใช้งานเลย์เอาต์ OpenType ของตนเองและอนุญาต เครื่องมือออกแบบสำหรับดึงดูดผู้คนในระดับต่ำกว่า สำหรับการดำเนินการต่างๆ เช่น การใช้ตัวกรองเวกเตอร์หรือ เปลี่ยนบนรูปร่างรูปอักขระ
  • นักพัฒนาซอฟต์แวร์อาจมีชุดแบบอักษรเดิมสำหรับแอปพลิเคชันของตนซึ่งนำมาสู่เว็บ หากต้องการใช้สแต็กเหล่านี้ โดยปกติจะต้องมีสิทธิ์เข้าถึงข้อมูลแบบอักษรโดยตรง แต่แบบอักษรของเว็บต้องไม่มี ให้ไว้
  • แบบอักษรบางรายการอาจไม่ได้รับอนุญาตให้แสดงผลบนเว็บ ตัวอย่างเช่น Linotype มีใบอนุญาตสำหรับ แบบอักษรบางแบบที่มีเฉพาะการใช้งานบนเดสก์ท็อป

Local Font Access API เป็นความพยายามในการแก้ปัญหาเหล่านี้ ซึ่งประกอบด้วย 2 ส่วน ดังนี้

  • API การระบุแบบอักษร ซึ่งช่วยให้ผู้ใช้ให้สิทธิ์เข้าถึงชุดเต็มของระบบที่พร้อมใช้งาน แบบอักษร
  • จากผลลัพธ์การแจกแจงแต่ละรายการ ความสามารถในการขอคอนเทนเนอร์ SFNT ระดับต่ำ (แบบไบต์) สิทธิ์การเข้าถึงที่มีข้อมูลแบบอักษรทั้งหมด

การสนับสนุนเบราว์เซอร์

การรองรับเบราว์เซอร์

  • Chrome: 103
  • ขอบ: 103
  • Firefox: ไม่สนับสนุน
  • Safari: ไม่รองรับ

แหล่งที่มา

วิธีใช้ Local Font Access API

การตรวจหาฟีเจอร์

หากต้องการตรวจสอบว่าระบบรองรับ Local Font Access API หรือไม่ ให้ใช้รายการต่อไปนี้

if ('queryLocalFonts' in window) {
  // The Local Font Access API is supported
}

การระบุแบบอักษรในเครื่อง

หากต้องการดูรายการแบบอักษรที่ติดตั้งไว้ในเครื่อง คุณต้องเรียกใช้ window.queryLocalFonts() ครั้งแรก การดำเนินการนี้จะเรียกใช้ข้อความแจ้งสิทธิ์ ซึ่งผู้ใช้สามารถอนุมัติหรือปฏิเสธได้ หากผู้ใช้ อนุมัติแบบอักษรในเครื่องที่จะค้นหา เบราว์เซอร์จะแสดงผลอาร์เรย์ที่มีข้อมูลแบบอักษร ที่คุณสามารถวนซ้ำได้ แบบอักษรแต่ละแบบจะแสดงเป็นออบเจ็กต์ FontData ที่มีพร็อพเพอร์ตี้ family (เช่น "Comic Sans MS"), fullName (เช่น "Comic Sans MS"), postscriptName (เช่น เช่น "ComicSansMS") และ style (เช่น "Regular")

// Query for all available fonts and log metadata.
try {
  const availableFonts = await window.queryLocalFonts();
  for (const fontData of availableFonts) {
    console.log(fontData.postscriptName);
    console.log(fontData.fullName);
    console.log(fontData.family);
    console.log(fontData.style);
  }
} catch (err) {
  console.error(err.name, err.message);
}

หากคุณสนใจเฉพาะชุดย่อยของแบบอักษร คุณสามารถกรองแบบอักษรตาม PostScript ได้ ด้วยการเพิ่มพารามิเตอร์ postscriptNames

const availableFonts = await window.queryLocalFonts({
  postscriptNames: ['Verdana', 'Verdana-Bold', 'Verdana-Italic'],
});

การเข้าถึงข้อมูล SFNT

การเข้าถึง SFNT โดยสมบูรณ์สามารถเข้าถึงได้ผ่านทางเมธอด blob() ของ FontData ออบเจ็กต์ SFNT เป็นรูปแบบไฟล์แบบอักษรที่สามารถประกอบด้วยแบบอักษรอื่นๆ เช่น PostScript แบบอักษร TrueType, OpenType, Web Open Font Format (WOFF) และอื่นๆ

try {
  const availableFonts = await window.queryLocalFonts({
    postscriptNames: ['ComicSansMS'],
  });
  for (const fontData of availableFonts) {
    // `blob()` returns a Blob containing valid and complete
    // SFNT-wrapped font data.
    const sfnt = await fontData.blob();
    // Slice out only the bytes we need: the first 4 bytes are the SFNT
    // version info.
    // Spec: https://docs.microsoft.com/en-us/typography/opentype/spec/otff#organization-of-an-opentype-font
    const sfntVersion = await sfnt.slice(0, 4).text();

    let outlineFormat = 'UNKNOWN';
    switch (sfntVersion) {
      case '\x00\x01\x00\x00':
      case 'true':
      case 'typ1':
        outlineFormat = 'truetype';
        break;
      case 'OTTO':
        outlineFormat = 'cff';
        break;
    }
    console.log('Outline format:', outlineFormat);
  }
} catch (err) {
  console.error(err.name, err.message);
}

สาธิต

คุณสามารถดูการทำงานของ Local Font Access API ได้ใน สาธิตด้านล่าง และอย่าลืมสำรวจ ซอร์สโค้ด เดโม แสดงองค์ประกอบที่กำหนดเองชื่อ <font-select> ซึ่ง จะใช้เครื่องมือเลือกแบบอักษรในเครื่อง

ข้อควรพิจารณาเกี่ยวกับความเป็นส่วนตัว

ดูเหมือนว่าสิทธิ์ "local-fonts" มีพื้นผิวที่มีลายนิ้วมือสูง อย่างไรก็ตาม เบราว์เซอร์สามารถส่งคืนอะไรก็ได้ที่ต้องการ ตัวอย่างเช่น เบราว์เซอร์ที่มุ่งเน้นการไม่ระบุตัวตนอาจเลือก เพื่อจัดเตรียมชุดแบบอักษรเริ่มต้นที่มีอยู่ในเบราว์เซอร์เท่านั้น ในทำนองเดียวกัน เบราว์เซอร์ไม่จำเป็น เพื่อให้ข้อมูลตารางตรงตามที่ปรากฏในดิสก์

เมื่อใดก็ตามที่เป็นไปได้ Local Font Access API จะได้รับการออกแบบมาให้แสดงเฉพาะข้อมูลเท่านั้น ที่จำเป็นต่อการเปิดใช้กรณีการใช้งานที่กล่าวถึง API ระบบอาจสร้างรายการแบบอักษรที่ติดตั้งไว้ที่ไม่ได้อยู่ใน แบบสุ่มหรือตามลำดับที่จัดเรียง โดยเรียงตามลำดับการติดตั้งแบบอักษร กำลังแสดงรายการ แบบอักษรที่ติดตั้งจาก API ของระบบดังกล่าวสามารถแสดงข้อมูลเพิ่มเติมที่อาจถูกใช้เพื่อ การเก็บลายนิ้วมือ และกรณีการใช้งานที่เราต้องการเปิดใช้จะไม่ได้รับการสนับสนุนโดยการรักษาลำดับนี้ไว้ เพื่อ API นี้กำหนดให้มีการจัดเรียงข้อมูลที่ส่งคืนก่อนที่จะส่งคืน

ความปลอดภัยและสิทธิ์

ทีม Chrome ได้ออกแบบและติดตั้ง Local Font Access API โดยใช้หลักการที่เป็นหัวใจสำคัญ ที่กำหนดไว้ในการควบคุมการเข้าถึงฟีเจอร์แพลตฟอร์มเว็บที่มีประสิทธิภาพ ซึ่งรวมถึงผู้ใช้ การควบคุม ความโปร่งใส และการยศาสตร์

การควบคุมของผู้ใช้

การเข้าถึงแบบอักษรของผู้ใช้อยู่ภายใต้การควบคุมโดยสมบูรณ์และจะไม่ได้รับอนุญาต เว้นแต่ "local-fonts" ตามที่ระบุไว้ใน รีจิสทรีสิทธิ์ได้รับสิทธิ์แล้ว

ความโปร่งใส

เว็บไซต์ได้รับสิทธิ์เข้าถึงแบบอักษรในเครื่องของผู้ใช้หรือไม่จะปรากฏใน แผ่นข้อมูลเว็บไซต์

ความต่อเนื่องของสิทธิ์

สิทธิ์ "local-fonts" จะยังคงอยู่ในระหว่างการโหลดหน้าซ้ำ สามารถเพิกถอนได้ผ่าน ข้อมูลเว็บไซต์

ความคิดเห็น

ทีม Chrome ต้องการทราบประสบการณ์ของคุณเมื่อใช้ Local Font Access API

บอกเราเกี่ยวกับการออกแบบ API

มีบางอย่างเกี่ยวกับ API ที่ทำงานไม่ได้ตามที่คาดหวังหรือไม่ หรือมีวิธีการที่ขาดหายไป หรือผลิตภัณฑ์ได้ง่ายที่คุณจำเป็นต้องใช้เพื่อนำความคิดของคุณไปปฏิบัติ มีคำถามหรือความคิดเห็นเกี่ยวกับความปลอดภัย รุ่นอะไร แจ้งปัญหาเกี่ยวกับที่เก็บ GitHub ที่เกี่ยวข้อง หรือเพิ่มความเห็นของคุณลงใน ปัญหาที่มีอยู่

รายงานปัญหาเกี่ยวกับการติดตั้งใช้งาน

คุณพบข้อบกพร่องในการติดตั้งใช้งาน Chrome ไหม หรือการติดตั้งใช้งานแตกต่างจากข้อกําหนดหรือไม่ รายงานข้อบกพร่องที่ new.crbug.com อย่าลืมใส่รายละเอียดให้มากที่สุด วิธีการง่ายๆ ในการทำซ้ำ และป้อน Blink>Storage>FontAccess ในช่องคอมโพเนนต์ ภาพ Glitch เหมาะสำหรับการแชร์ซ้ำที่ง่ายและรวดเร็ว

แสดงการรองรับ API

คุณวางแผนที่จะใช้ Local Font Access API ไหม การสนับสนุนสาธารณะของคุณช่วยให้ทีม Chrome ทำสิ่งต่อไปนี้ จัดลำดับความสำคัญของฟีเจอร์และแสดงให้ผู้ให้บริการเบราว์เซอร์รายอื่นเห็นความสำคัญของการสนับสนุนเหล่านั้น

ส่งทวีตไปยัง @ChromiumDev โดยใช้แฮชแท็ก #LocalFontAccess และให้ ให้เราทราบสถานที่และวิธีที่คุณใช้งาน

กิตติกรรมประกาศ

มีการแก้ไขข้อกำหนดของ API การเข้าถึงแบบอักษรในเครื่องโดย Emil A. Eklund Alex Russell Joshua Bell และ Olivier Yiptong บทความนี้ได้รับการตรวจสอบโดย Joe Medley Dominik Röttsches และ Olivier Yiptong รูปภาพหลักโดย Brett Jordan ในช่อง หน้าจอแนะนํา