บทแนะนำ: ย้ายข้อมูลไปยังไฟล์ Manifest V2

เราเลิกใช้งานไฟล์ Manifest เวอร์ชัน 1 ใน Chrome 18 และจะหยุดการรองรับตามกำหนดการรองรับไฟล์ Manifest เวอร์ชัน 1 การเปลี่ยนแปลงจากเวอร์ชัน 1 เป็นเวอร์ชัน 2 อยู่ใน 2 หมวดหมู่หลัก ได้แก่ การเปลี่ยนแปลง API และการเปลี่ยนแปลงด้านความปลอดภัย

เอกสารนี้มีรายการตรวจสอบสำหรับการย้ายข้อมูลส่วนขยาย Chrome จากไฟล์ Manifest เวอร์ชัน 1 ไปยังเวอร์ชัน 2 ตามด้วยข้อมูลสรุปโดยละเอียดเพิ่มเติมเกี่ยวกับความหมายของการเปลี่ยนแปลงเหล่านี้และเหตุผลที่ทำการเปลี่ยนแปลง

รายการตรวจสอบการเปลี่ยนแปลง API

  • คุณใช้พร็อพเพอร์ตี้ browser_actions หรือ chrome.browserActions API

  • แทนที่ browser_actions ด้วยพร็อพเพอร์ตี้ browser_action แบบเอกพจน์

  • แทนที่ chrome.browserActions ด้วย chrome.browserAction

  • แทนที่พร็อพเพอร์ตี้ icons ด้วย default_icon

  • แทนที่พร็อพเพอร์ตี้ name ด้วย default_title

  • แทนที่พร็อพเพอร์ตี้ popup ด้วย default_popup (และตอนนี้ต้องเป็นสตริง)

  • คุณใช้พร็อพเพอร์ตี้ page_actions หรือ chrome.pageActions API

  • แทนที่ page_actions ด้วย page_action

  • แทนที่ chrome.pageActions ด้วย chrome.pageAction

  • แทนที่พร็อพเพอร์ตี้ icons ด้วย default_icon

  • แทนที่พร็อพเพอร์ตี้ name ด้วย default_title

  • แทนที่พร็อพเพอร์ตี้ popup ด้วย default_popup (และตอนนี้ต้องเป็นสตริง)

  • คุณใช้พร็อพเพอร์ตี้ chrome.self อยู่ใช่ไหม

  • แทนที่ด้วย chrome.extension

  • คุณใช้พร็อพเพอร์ตี้ Port.tab อยู่ใช่ไหม

  • แทนที่ด้วย Port.sender

  • คุณใช้ chrome.extension.getTabContentses() หรือ chrome.extension.getExtensionTabs() API

  • แทนที่ด้วย chrome.extension.getViews( { "type" : "tab" } )

  • ส่วนขยายของคุณใช้หน้าพื้นหลังหรือไม่

  • แทนที่พร็อพเพอร์ตี้ background_page ด้วยพร็อพเพอร์ตี้ background

  • เพิ่มพร็อพเพอร์ตี้ scripts หรือ page ที่มีโค้ดสำหรับหน้าเว็บ

  • เพิ่มpersistentพร็อพเพอร์ตี้และตั้งค่าเป็น false เพื่อแปลงหน้าพื้นหลังเป็นหน้ากิจกรรม

รายการตรวจสอบการเปลี่ยนแปลงด้านความปลอดภัย

  • คุณใช้บล็อกสคริปต์แบบอินไลน์ในหน้า HTML ใช่ไหม

  • นำโค้ด JS ที่อยู่ในแท็ก <script> ออก แล้ววางไว้ในไฟล์ JS ภายนอก

  • คุณใช้ตัวแฮนเดิลเหตุการณ์แบบอินไลน์ (เช่น onclick ฯลฯ) หรือไม่

  • นำออกจากโค้ด HTML ย้ายไปยังไฟล์ JS ภายนอก แล้วใช้ addEventListener() แทน

  • ส่วนขยายของคุณแทรกสคริปต์เนื้อหาลงในหน้าเว็บที่ต้องเข้าถึงทรัพยากร (เช่น รูปภาพและสคริปต์) ที่อยู่ในแพ็กเกจของส่วนขยายหรือไม่

  • กำหนดพร็อพเพอร์ตี้ web_accessible_resources และแสดงรายการทรัพยากร (และอาจมีนโยบายรักษาความปลอดภัยเนื้อหาแยกต่างหากสำหรับทรัพยากรเหล่านั้น)

  • ส่วนขยายของคุณฝังหน้าเว็บภายนอกหรือไม่

  • กำหนดพร็อพเพอร์ตี้ sandbox

  • โค้ดหรือไลบรารีของคุณใช้ eval(), Function() ใหม่, innerHTML, setTimeout() หรือ ส่งสตริงของโค้ด JS ที่ได้รับการประเมินแบบไดนามิกหรือไม่

  • ใช้ JSON.parse() หากคุณแยกวิเคราะห์โค้ด JSON เป็นออบเจ็กต์

  • ใช้ไลบรารีที่รองรับ CSP เช่น AngularJS

  • สร้างรายการแซนด์บ็อกซ์ในไฟล์ Manifest และเรียกใช้โค้ดที่ได้รับผลกระทบในแซนด์บ็อกซ์โดยใช้ postMessage() เพื่อสื่อสารกับหน้าเว็บที่อยู่ในแซนด์บ็อกซ์

  • คุณกำลังโหลดโค้ดภายนอก เช่น jQuery หรือ Google Analytics ใช่ไหม

  • ลองดาวน์โหลดไลบรารีและแพ็กเกจในส่วนขยาย จากนั้นโหลดจากแพ็กเกจในเครื่อง

  • เพิ่มโดเมน HTTPS ที่แสดงทรัพยากรในส่วน "content_security_policy" ของไฟล์ Manifest ลงในรายการที่อนุญาต

สรุปการเปลี่ยนแปลง API

Manifest เวอร์ชัน 2 มีการเปลี่ยนแปลงเล็กน้อยใน API การทำงานของเบราว์เซอร์และ API การทำงานของหน้าเว็บ และแทนที่ API เก่าบางรายการด้วย API ใหม่กว่า

การเปลี่ยนแปลงการดำเนินการในเบราว์เซอร์

API การดำเนินการในเบราว์เซอร์มีการเปลี่ยนแปลงการตั้งชื่อดังนี้

  • พร็อพเพอร์ตี้ browser_actions และ chrome.browserActions ถูกแทนที่ด้วยพร็อพเพอร์ตี้เอกพจน์ที่เกี่ยวข้อง อย่าง browser_action และ chrome.browserAction
  • ในพร็อพเพอร์ตี้ browser_actions เดิมมีพร็อพเพอร์ตี้ icons, name และ popup โดยเราได้แทนที่ด้วยรายการต่อไปนี้

  • default_icon สำหรับไอคอนป้ายการทำงานของเบราว์เซอร์

  • default_name สำหรับข้อความที่ปรากฏในเคล็ดลับเครื่องมือเมื่อวางเมาส์เหนือป้าย

  • default_popup สำหรับหน้า HTML ที่แสดง UI สำหรับการดำเนินการของเบราว์เซอร์ (และตอนนี้ต้องเป็นสตริง จะเป็นออบเจ็กต์ไม่ได้)

การเปลี่ยนแปลงการดำเนินการของหน้าเว็บ

API การทำงานของหน้าเว็บมีการเปลี่ยนแปลงเช่นเดียวกับการเปลี่ยนแปลงสำหรับการทำงานของเบราว์เซอร์ ดังนี้

  • ระบบได้แทนที่พร็อพเพอร์ตี้ page_actions และ chrome.pageActions ด้วยพร็อพเพอร์ตี้เอกพจน์ที่เทียบเท่ากัน page_action และ chrome.pageAction
  • ในพร็อพเพอร์ตี้ page_actions เดิมมีพร็อพเพอร์ตี้ icons, name และ popup โดยจะแทนที่ด้วยรายการต่อไปนี้

  • default_icon สำหรับไอคอนป้ายการทำงานบนหน้าเว็บ

  • default_name สำหรับข้อความที่ปรากฏในเคล็ดลับเครื่องมือเมื่อวางเมาส์เหนือป้าย

  • default_popup สำหรับหน้า HTML ที่แสดง UI สำหรับการดำเนินการในหน้า (และตอนนี้ต้องเป็นสตริง ไม่ใช่ออบเจ็กต์)

API ที่นำออกและเปลี่ยนแปลง

เราได้นำ API ของส่วนขยายบางรายการออกและแทนที่ด้วย API ใหม่ ดังนี้

  • พร็อพเพอร์ตี้ background_page ถูกแทนที่ด้วย background แล้ว
  • นำพร็อพเพอร์ตี้ chrome.self ออกแล้ว โปรดใช้ chrome.extension
  • พร็อพเพอร์ตี้ Port.tab ถูกแทนที่ด้วย Port.sender แล้ว
  • chrome.extension.getTabContentses() และ chrome.extension.getExtensionTabs() API ถูกแทนที่ด้วย chrome.extension.getViews( { "type" : "tab" } ) แล้ว

สรุปการเปลี่ยนแปลงด้านความปลอดภัย

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

ไม่อนุญาตให้ใช้สคริปต์และตัวแฮนเดิลเหตุการณ์แบบอินไลน์

เนื่องจากการใช้นโยบายรักษาความปลอดภัยเนื้อหา คุณจึงใช้แท็ก <script> ที่อยู่ในเนื้อหา HTML ไม่ได้อีกต่อไป โดยต้องย้ายไปยังไฟล์ JS ภายนอก นอกจากนี้ ระบบยังไม่รองรับตัวแฮนเดิลเหตุการณ์ในบรรทัด ด้วย ตัวอย่างเช่น สมมติว่าคุณมีโค้ดต่อไปนี้ในส่วนขยาย

<html>
<head>
  <script>
    function myFunc() { ... }
  </script>
</head>
</html>

โค้ดนี้จะทำให้เกิดข้อผิดพลาดในรันไทม์ หากต้องการแก้ไขปัญหานี้ ให้ย้ายเนื้อหาแท็ก <script> ไปยังไฟล์ภายนอก และอ้างอิงด้วยแอตทริบิวต์ src='path_to_file.js'

ในทำนองเดียวกัน ตัวแฮนเดิลเหตุการณ์แบบอินไลน์ซึ่งเป็นฟีเจอร์ที่พบได้ทั่วไปและอำนวยความสะดวกที่นักพัฒนาเว็บหลายคนใช้จะไม่ทำงาน ตัวอย่างเช่น ให้พิจารณากรณีที่พบบ่อย เช่น

<body onload="initialize()">
<button onclick="handleClick()" id="button1">

ซึ่งจะใช้ในส่วนขยาย Manifest V2 ไม่ได้ นำตัวแฮนเดิลเหตุการณ์ในบรรทัดออก วางไว้ในไฟล์ JS ภายนอก แล้วใช้ addEventListener() เพื่อลงทะเบียนตัวแฮนเดิลเหตุการณ์แทน เช่น ในโค้ด JS ให้ใช้

window.addEventListener("load", initialize);
...
document.getElementById("button1").addEventListener("click",handleClick);

ซึ่งเป็นวิธีที่สะอาดกว่ามากในการแยกลักษณะการทำงานของส่วนขยายออกจากมาร์กอัปของอินเทอร์เฟซผู้ใช้

การฝังเนื้อหา

ในบางสถานการณ์ ส่วนขยายอาจฝังเนื้อหาที่ใช้ภายนอกได้หรือมาจากแหล่งที่มาภายนอก

เนื้อหาส่วนขยายในหน้าเว็บ: หากส่วนขยายฝังทรัพยากร (เช่น รูปภาพ สคริปต์ รูปแบบ CSS ฯลฯ) ที่ใช้ใน Content Script ที่แทรกลงในหน้าเว็บ คุณต้องใช้พร็อพเพอร์ตี้ web_accessible_resources เพื่อเพิ่มทรัพยากรเหล่านี้ลงในรายการที่อนุญาตเพื่อให้หน้าเว็บภายนอกใช้ทรัพยากรเหล่านั้นได้

{
...
  "web_accessible_resources": [
    "images/image1.png",
    "script/myscript.js"
  ],
...
}

การฝังเนื้อหาภายนอก: นโยบายรักษาความปลอดภัยเนื้อหาอนุญาตให้โหลดสคริปต์และออบเจ็กต์ในเครื่องจากแพ็กเกจของคุณเท่านั้น ซึ่ง ป้องกันไม่ให้ผู้โจมตีภายนอกนำโค้ดที่ไม่รู้จักมาใส่ในส่วนขยาย อย่างไรก็ตาม บางครั้งคุณอาจต้องการโหลดทรัพยากรที่ให้บริการภายนอก เช่น โค้ด jQuery หรือ Google Analytics ทำได้ 2 วิธีดังนี้

  1. ดาวน์โหลดไลบรารีที่เกี่ยวข้องในเครื่อง (เช่น jQuery) และแพ็กเกจกับส่วนขยาย
  2. คุณลด CSP ได้แบบจำกัดโดยเพิ่มแหล่งที่มาของ HTTPS ลงในรายการที่อนุญาตในส่วน "content_security_policy" ของไฟล์ Manifest หากต้องการรวมไลบรารี เช่น Google Analytics ให้ใช้วิธีต่อไปนี้

    {
      ...,
      "content_security_policy": "script-src 'self'
      https://ssl.google-analytics.com; object-src 'self'",
      ...
    }
    

การใช้การประเมินสคริปต์แบบไดนามิก

การเปลี่ยนแปลงที่สำคัญที่สุดอย่างหนึ่งในรูปแบบไฟล์ Manifest V2 ใหม่คือส่วนขยายไม่สามารถใช้เทคนิคการประเมินสคริปต์แบบไดนามิก เช่น eval() หรือ Function() ใหม่ หรือส่งสตริงของโค้ด JS ไปยังฟังก์ชันที่จะทำให้มีการใช้ eval() เช่น setTimeout() ได้อีกต่อไป นอกจากนี้ เรายังทราบว่าไลบรารี JavaScript บางอย่างที่ใช้กันโดยทั่วไป เช่น Google Maps และไลบรารีการสร้างเทมเพลตบางอย่าง ใช้เทคนิคเหล่านี้บางอย่าง

Chrome มีแซนด์บ็อกซ์ให้หน้าเว็บทำงานในต้นทางของตัวเอง ซึ่งจะถูกปฏิเสธการเข้าถึง chrome.* API หากต้องการใช้ eval() และอื่นๆ ภายใต้นโยบายรักษาความปลอดภัยเนื้อหาใหม่ ให้ทำดังนี้

  1. สร้างรายการแซนด์บ็อกซ์ในไฟล์ Manifest
  2. ในรายการแซนด์บ็อกซ์ ให้ระบุหน้าเว็บที่ต้องการเรียกใช้ในแซนด์บ็อกซ์
  3. ใช้การส่งข้อความผ่าน postMessage() เพื่อสื่อสารกับหน้าเว็บที่อยู่ในแซนด์บ็อกซ์

ดูรายละเอียดเพิ่มเติมเกี่ยวกับวิธีดำเนินการนี้ได้ในเอกสารประกอบเกี่ยวกับ Sandboxing Eval

อ่านเพิ่มเติม

การเปลี่ยนแปลงในไฟล์ Manifest เวอร์ชัน 2 ออกแบบมาเพื่อเป็นแนวทางให้นักพัฒนาซอฟต์แวร์สร้างส่วนขยายและแอปที่มีความปลอดภัยมากขึ้นและมีสถาปัตยกรรมที่แข็งแกร่ง ดูรายการการเปลี่ยนแปลงทั้งหมดจากไฟล์ Manifest เวอร์ชัน 1 เป็นเวอร์ชัน 2 ได้ในเอกสารประกอบของไฟล์ Manifest ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้แซนด์บ็อกซ์ เพื่อแยกโค้ดที่ไม่ปลอดภัยได้ที่บทความeval ของแซนด์บ็อกซ์ ดูข้อมูลเพิ่มเติมเกี่ยวกับนโยบายความปลอดภัยของเนื้อหาได้โดยไปที่บทแนะนำที่เกี่ยวข้องกับส่วนขยายและคำแนะนำที่ดีใน HTML5Rocks