สคริปต์เนื้อหาจะดำเนินการใน"โลกโดดเดี่ยว" สภาพแวดล้อม คุณต้องฉีดstate()
วิธีการของคุณลงในหน้าตัวเอง
เมื่อคุณต้องการที่จะใช้อย่างใดอย่างหนึ่งของchrome.*
APIs ในสคริปต์คุณจะต้องดำเนินการจัดการเหตุการณ์พิเศษที่อธิบายไว้ในคำตอบนี้: ส่วนขยายของ Chrome - เรียกข้อความต้นฉบับของ
มิฉะนั้นหากคุณไม่จำเป็นต้องใช้chrome.*
API ฉันขอแนะนำอย่างยิ่งให้ฉีดรหัส JS ของคุณทั้งหมดในหน้าผ่านการเพิ่ม<script>
แท็ก:
สารบัญ
- วิธีที่ 1: ฉีดไฟล์อื่น
- วิธีที่ 2: ฉีดรหัสฝังตัว
- วิธีที่ 2b: การใช้ฟังก์ชัน
- วิธีที่ 3: การใช้เหตุการณ์แบบอินไลน์
- ค่าแบบไดนามิกในรหัสที่ฉีด
วิธีที่ 1: ฉีดไฟล์อื่น
นี่เป็นวิธีที่ง่ายที่สุด / ดีที่สุดเมื่อคุณมีรหัสจำนวนมาก รวมรหัส JS จริงของคุณลงในไฟล์ภายในส่วนขยายของคุณscript.js
ด้วย จากนั้นให้สคริปต์เนื้อหาของคุณเป็นดังนี้ (อธิบายที่นี่: Google Chome“ จาวาสคริปต์ทางลัด” จาวาสคริปต์ที่กำหนดเอง ):
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('script.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
หมายเหตุ: หากคุณใช้วิธีนี้script.js
ไฟล์ที่ถูกฉีดจะต้องถูกเพิ่มเข้าไปใน"web_accessible_resources"
ส่วน ( ตัวอย่าง ) หากคุณไม่ใช้ Chrome จะปฏิเสธที่จะโหลดสคริปต์ของคุณและแสดงข้อผิดพลาดต่อไปนี้ในคอนโซล:
กำลังปฏิเสธการโหลด chrome-extension: // [EXTENSIONID] /script.js ทรัพยากรจะต้องอยู่ในรายการรายการ web_accessible_resources เพื่อที่จะโหลดหน้าเว็บที่อยู่นอกส่วนขยาย
วิธีที่ 2: ฉีดรหัสฝังตัว
วิธีนี้มีประโยชน์เมื่อคุณต้องการเรียกใช้โค้ดขนาดเล็กอย่างรวดเร็ว (ดูเพิ่มเติมที่: วิธีปิดการใช้งานปุ่มลัด facebook ด้วยส่วนขยายของ Chrome )
var actualCode = `// Code here.
// If you want to use a variable, use $ and curly braces.
// For example, to use a fixed random number:
var someFixedRandomValue = ${ Math.random() };
// NOTE: Do not insert unsafe variables in this way, see below
// at "Dynamic values in the injected code"
`;
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
หมายเหตุ: รองรับเทมเพลตตัวอักษรใน Chrome 41 ขึ้นไป หากคุณต้องการให้ส่วนขยายทำงานใน Chrome 40- ให้ใช้:
var actualCode = ['/* Code here. Example: */' + 'alert(0);',
'// Beware! This array have to be joined',
'// using a newline. Otherwise, missing semicolons',
'// or single-line comments (//) will mess up your',
'// code ----->'].join('\n');
วิธีที่ 2b: การใช้ฟังก์ชัน
สำหรับโค้ดขนาดใหญ่การอ้างอิงสตริงนั้นไม่สามารถทำได้ แทนที่จะใช้อาร์เรย์คุณสามารถใช้ฟังก์ชันและสร้างสตริงได้:
var actualCode = '(' + function() {
// All code is executed in a local scope.
// For example, the following does NOT overwrite the global `alert` method
var alert = null;
// To overwrite a global variable, prefix `window`:
window.alert = null;
} + ')();';
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
วิธีนี้ใช้งานได้เนื่องจากตัว+
ดำเนินการบนสตริงและฟังก์ชันแปลงวัตถุทั้งหมดเป็นสตริง หากคุณตั้งใจจะใช้รหัสมากกว่าหนึ่งครั้งคุณควรสร้างฟังก์ชันเพื่อหลีกเลี่ยงการทำซ้ำรหัส การใช้งานอาจมีลักษณะดังนี้:
function injectScript(func) {
var actualCode = '(' + func + ')();'
...
}
injectScript(function() {
alert("Injected script");
});
หมายเหตุ: เนื่องจากฟังก์ชั่นนั้นเป็นแบบอนุกรมขอบเขตดั้งเดิมและคุณสมบัติที่ถูกผูกไว้ทั้งหมดจะหายไป!
var scriptToInject = function() {
console.log(typeof scriptToInject);
};
injectScript(scriptToInject);
// Console output: "undefined"
วิธีที่ 3: การใช้เหตุการณ์แบบอินไลน์
บางครั้งคุณต้องการเรียกใช้รหัสบางอย่างทันทีเช่นเรียกใช้รหัสก่อนที่<head>
จะสร้างองค์ประกอบ สิ่งนี้สามารถทำได้โดยการแทรก<script>
แท็กด้วยtextContent
(ดูวิธี 2 / 2b)
ทางเลือกอื่นแต่ไม่แนะนำคือให้ใช้เหตุการณ์แบบอินไลน์ ไม่แนะนำเนื่องจากหากหน้ากำหนดนโยบายความปลอดภัยเนื้อหาที่ห้ามสคริปต์แบบอินไลน์ผู้ฟังเหตุการณ์แบบอินไลน์จะถูกบล็อก สคริปต์แบบอินไลน์ฉีดโดยส่วนขยายในขณะที่ยังคงทำงาน หากคุณยังต้องการใช้เหตุการณ์แบบอินไลน์นี่คือวิธี:
var actualCode = '// Some code example \n' +
'console.log(document.documentElement.outerHTML);';
document.documentElement.setAttribute('onreset', actualCode);
document.documentElement.dispatchEvent(new CustomEvent('reset'));
document.documentElement.removeAttribute('onreset');
หมายเหตุ: วิธีการนี้จะถือว่าไม่มีผู้ฟังเหตุการณ์ระดับโลกรายอื่นที่จัดการกับreset
เหตุการณ์ หากมีคุณยังสามารถเลือกหนึ่งในกิจกรรมระดับโลกอื่น ๆ เพียงเปิดคอนโซล JavaScript (F12) พิมพ์document.documentElement.on
และเลือกกิจกรรมที่มี
ค่าแบบไดนามิกในรหัสที่ฉีด
ในบางครั้งคุณต้องส่งตัวแปรตามอำเภอใจไปยังฟังก์ชันที่ฉีด ตัวอย่างเช่น:
var GREETING = "Hi, I'm ";
var NAME = "Rob";
var scriptToInject = function() {
alert(GREETING + NAME);
};
ในการฉีดโค้ดนี้คุณจะต้องส่งตัวแปรเป็นอาร์กิวเมนต์ไปยังฟังก์ชันที่ไม่ระบุตัวตน อย่าลืมนำไปใช้อย่างถูกต้อง! ต่อไปนี้จะไม่ทำงาน:
var scriptToInject = function (GREETING, NAME) { ... };
var actualCode = '(' + scriptToInject + ')(' + GREETING + ',' + NAME + ')';
// The previous will work for numbers and booleans, but not strings.
// To see why, have a look at the resulting string:
var actualCode = "(function(GREETING, NAME) {...})(Hi, I'm ,Rob)";
// ^^^^^^^^ ^^^ No string literals!
การแก้ปัญหาคือการใช้JSON.stringify
ก่อนที่จะผ่านการโต้แย้ง ตัวอย่าง:
var actualCode = '(' + function(greeting, name) { ...
} + ')(' + JSON.stringify(GREETING) + ',' + JSON.stringify(NAME) + ')';
หากคุณมีตัวแปรหลายตัวมันควรใช้JSON.stringify
เพียงครั้งเดียวเพื่อปรับปรุงความสามารถในการอ่านดังนี้:
...
} + ')(' + JSON.stringify([arg1, arg2, arg3, arg4]) + ')';
player.addEventListener("onStateChange", state);