วิธีใช้ jQuery ในส่วนขยาย Chrome


129

ฉันกำลังเขียนนามสกุลโครเมี่ยม และฉันต้องการใช้jQueryในส่วนขยายของฉัน ฉันไม่ได้ใช้พื้นหลังหน้าเพียงแค่พื้นหลังสคริปต์

นี่คือไฟล์ของฉัน:

manifest.json

{
    "manifest_version": 2,

    "name": "Extension name",
    "description": "This extension does something,",
    "version": "0.1",

    "permissions": [
        "activeTab"
    ],

    "browser_action": {
        "default_icon": "images/icon_128.png"
    },

    "background": {
        "scripts": ["background.js"],
        "persistent": false
    },

    "icons": {
        "16": "images/icon_16.png",
        "48": "images/icon_48.png",
        "128": "images/icon_128.png"
    }
}

ของฉัน background.jsไฟล์เพิ่งเรียกใช้ไฟล์อื่นชื่อwork.js

// Respond to the click on extension Icon
chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.tabs.executeScript({
        file: 'work.js'
    });
});

work.jsตรรกะหลักของส่วนขยายของฉันที่อยู่ภายใน เนื้อหาที่ฉันคิดว่าไม่สำคัญสำหรับคำถามนี้

สิ่งที่ฉันต้องการถามคือฉันจะใช้ jQuery ในส่วนขยายของฉันได้อย่างไร เนื่องจากฉันไม่ได้ใช้หน้าพื้นหลังใด ๆ ฉันไม่สามารถเพิ่ม jQuery เข้าไปได้ ฉันจะเพิ่มและใช้ jQuery ในส่วนขยายของฉันได้อย่างไร?

ฉันลองเรียกใช้ jQuery พร้อมกับ work.js จากbackground.jsไฟล์

// Respond to the click on extension Icon
chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.tabs.executeScript({
        file: 'thirdParty/jquery-2.0.3.js'
    });
    chrome.tabs.executeScript({
        file: 'work.js'
    });
});

และใช้งานได้ดี แต่ฉันมีความกังวลว่าสคริปต์ที่เพิ่มเข้ามาเพื่อดำเนินการในลักษณะนี้จะดำเนินการแบบอะซิงโครนัสหรือไม่ ถ้าใช่มันอาจเกิดขึ้นได้ที่ work.js ทำงานด้วยซ้ำก่อน jQuery (หรือไลบรารีอื่น ๆ ที่ฉันอาจเพิ่มในอนาคต)

และฉันอยากทราบด้วยว่าวิธีใดเป็นวิธีที่ถูกต้องและดีที่สุดในการใช้ไลบรารีของบุคคลที่สามในส่วนขยาย Chrome ของฉัน


2
วิธีที่ถูกต้องคือวนิลา!
bjb568

หากคุณกำลังมองหาวิธีเพิ่ม jQuery ในส่วนขยายป๊อปอัป (เหมือนที่ฉันเคยเป็น) โปรดดูคำถามนี้: stackoverflow.com/questions/12035242/…
Pro Q

คำตอบ:


125

คุณต้องเพิ่มสคริปต์ jquery ของคุณในโปรเจ็กต์ส่วนขยาย chrome และในbackgroundส่วนของ manifest.json ของคุณดังนี้:

  "background":
    {
        "scripts": ["thirdParty/jquery-2.0.3.js", "background.js"]
    }

หากคุณต้องการ jquery ใน content_scripts คุณต้องเพิ่มในไฟล์ Manifest ด้วย:

"content_scripts": 
    [
        {
            "matches":["http://website*"],
            "js":["thirdParty/jquery.1.10.2.min.js", "script.js"],
            "css": ["css/style.css"],
            "run_at": "document_end"
        }
    ]

นี่คือสิ่งที่ฉันทำ

นอกจากนี้หากฉันจำได้ถูกต้องสคริปต์พื้นหลังจะทำงานในหน้าต่างพื้นหลังที่คุณสามารถเปิดchrome://extensionsได้


7
คุณหมายถึงอะไรกันแน่You have to add your jquery script to your chrome-extension project? ฉันทำสิ่งนี้: manifest.json: "background": { `" scripts ": [" thirdParty / jquery-2.0.3.js "," background.js "]," "persistent": false` `},` และฉันได้ดาวน์โหลด jQuery ไปยังโฟลเดอร์ thirdParty อย่างไรก็ตามฉันยังไม่สามารถใช้ jQuery ได้ มันทำให้เกิดข้อผิดพลาด: Uncaught ReferenceError: $ is not defined ฉันเพิ่มสิ่งนี้ลงในwork.jsไฟล์เพื่อทดสอบ $("body").html("Foo!");
Ishan

ความคิดเห็นด้านบนดูเหมือนจะยุ่งเหยิง แต่ในขณะที่เพิ่มความคิดเห็นจะไม่แสดงตัวอย่าง โปรดยกโทษให้ฉันด้วย
Ishan

ฉันหมายถึงเพิ่มลงในโฟลเดอร์ส่วนขยาย chrome ของคุณ เช่น /home/you/chromexetension_source_files/thirdParty/jquery-2.0.3.js คุณควรทำสิ่งเดียวกันกับ work.js ของคุณ
Nico

1
ฉันพยายามทำตามที่คุณพูดแล้ว แต่ฉันยังคงได้รับข้อผิดพลาดเดิมที่ไม่สามารถเข้าถึง jquery จากwork.jsไฟล์ของฉันได้ Uncaught ReferenceError: $ is not defined. หากทำได้โปรดอัปโหลดตัวอย่างการทำงานที่ไหนสักแห่ง ตัวอย่างง่ายๆเช่นการทำ '$ ("body"). html ("Foo!");' ใน work.js.
Ishan

7
ฉันยังมีปัญหาในการรับjQueryหรือ$รับรู้ ปรากฎว่าฉันอ้างอิง jQuery ล่าสุดในอาร์เรย์รายการ เมื่อใส่ครั้งแรกก็จำได้
BenR

18

มันง่ายมากเพียงทำสิ่งต่อไปนี้:

เพิ่มบรรทัดต่อไปนี้ใน manifest.json ของคุณ

"content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'",

ตอนนี้คุณมีอิสระในการโหลด jQuery โดยตรงจาก url

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>

ที่มา: google doc


1
จะเกิดอะไรขึ้นถ้าคุณมีหลายสคริปต์ที่จะโหลด?
อีก

1
คำตอบที่ดีหากคุณต้องการโหลดสคริปต์ของคุณจากเซิร์ฟเวอร์ระยะไกล (ซึ่งจำเป็นต้องให้คุณไว้วางใจเซิร์ฟเวอร์ระยะไกลด้วยส่วนขยายของคุณและทุกสิ่งที่เข้าถึงได้อย่างมีประสิทธิภาพ)
Nathaniel Verhaaren

1
@NathanielVerhaaren นี่เป็นประเด็นที่สมเหตุสมผลที่จะเพิ่ม แต่สามารถบรรเทาได้โดยการตรวจสอบแหล่งที่มาโดยใช้subresource integrity(SRI)
Dan Atkinson

13

และใช้งานได้ดี แต่ฉันมีความกังวลว่าสคริปต์ที่เพิ่มเข้ามาเพื่อดำเนินการในลักษณะนี้จะดำเนินการแบบอะซิงโครนัสหรือไม่ ถ้าใช่มันอาจเกิดขึ้นได้ที่ work.js ทำงานก่อน jQuery (หรือไลบรารีอื่น ๆ ที่ฉันอาจเพิ่มในอนาคต)

นั่นไม่ควรกังวลจริงๆ: คุณจัดคิวสคริปต์ที่จะดำเนินการในบริบท JS บางบริบทและบริบทนั้นไม่สามารถมีเงื่อนไขการแข่งขันได้เนื่องจากเป็นเธรดเดี่ยว

อย่างไรก็ตามวิธีที่เหมาะสมในการขจัดข้อกังวลนี้คือการต่อสาย:

chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.tabs.executeScript({
        file: 'thirdParty/jquery-2.0.3.js'
    }, function() {
        // Guaranteed to execute only after the previous script returns
        chrome.tabs.executeScript({
            file: 'work.js'
        });
    });
});

หรือโดยทั่วไป:

function injectScripts(scripts, callback) {
  if(scripts.length) {
    var script = scripts.shift();
    chrome.tabs.executeScript({file: script}, function() {
      if(chrome.runtime.lastError && typeof callback === "function") {
        callback(false); // Injection failed
      }
      injectScripts(scripts, callback);
    });
  } else {
    if(typeof callback === "function") {
      callback(true);
    }
  }
}

injectScripts(["thirdParty/jquery-2.0.3.js", "work.js"], doSomethingElse);

หรือสัญญา (และให้สอดคล้องกับลายเซ็นที่ถูกต้อง):

function injectScript(tabId, injectDetails) {
  return new Promise((resolve, reject) => {
    chrome.tabs.executeScript(tabId, injectDetails, (data) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError.message);
      } else {
        resolve(data);
      }
    });
  });
}

injectScript(null, {file: "thirdParty/jquery-2.0.3.js"}).then(
  () => injectScript(null, {file: "work.js"})
).then(
  () => doSomethingElse
).catch(
  (error) => console.error(error)
);

หรือทำไมไม่ห่าasync/ await-ed สำหรับไวยากรณ์ที่ชัดเจนยิ่งขึ้น:

function injectScript(tabId, injectDetails) {
  return new Promise((resolve, reject) => {
    chrome.tabs.executeScript(tabId, injectDetails, (data) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError.message);
      } else {
        resolve(data);
      }
    });
  });
}

try {
  await injectScript(null, {file: "thirdParty/jquery-2.0.3.js"});
  await injectScript(null, {file: "work.js"});
  doSomethingElse();
} catch (err) {
  console.error(err);
}

โปรดทราบว่าใน Firefox คุณสามารถใช้ได้browser.tabs.executeScriptเพราะจะส่งคืน Promise


วิธีแรกนั้นยอดเยี่ยม ในฐานะคนที่ไม่รู้จัก JavaScript มากนักฉันไม่เคยพิจารณาอะไรแบบนั้น
FriskySaga

11

นอกเหนือจากโซลูชันที่กล่าวไปแล้วคุณยังสามารถดาวน์โหลดjquery.min.jsในเครื่องแล้วใช้งานได้ -

สำหรับการดาวน์โหลด -

wget "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"

manifest.json -

"content_scripts": [
   {
    "js": ["/path/to/jquery.min.js", ...]
   }
],

ใน html -

<script src="/path/to/jquery.min.js"></script>

ข้อมูลอ้างอิง - https://developer.chrome.com/extensions/contentSecurityPolicy


3
นี่เป็นวิธีที่ดีที่สุด ... คุณไม่จำเป็นต้องมีส่วน html
c-an

1

ในกรณีของฉันมีโซลูชันการทำงานผ่านการส่งข้อความข้ามเอกสาร (XDM) และการดำเนินการส่วนขยาย Chrome ในคลิกแทนการโหลดหน้า

manifest.json

{
  "name": "JQuery Light",
  "version": "1",
  "manifest_version": 2,

  "browser_action": {
    "default_icon": "icon.png"
  },

  "content_scripts": [
    {
      "matches": [
        "https://*.google.com/*"
      ],
      "js": [
        "jquery-3.3.1.min.js",
        "myscript.js"
      ]
    }
  ],

  "background": {
    "scripts": [
      "background.js"
    ]
  }

}

background.js

chrome.browserAction.onClicked.addListener(function (tab) {
  chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
    var activeTab = tabs[0];
    chrome.tabs.sendMessage(activeTab.id, {"message": "clicked_browser_action"});
  });
});

MyScript.js

chrome.runtime.onMessage.addListener(
    function (request, sender, sendResponse) {
        if (request.message === "clicked_browser_action") {
        console.log('Hello world!')
        }
    }
);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.