Rumah  >  Soal Jawab  >  teks badan

Pekerja Perkhidmatan Gigih dalam Sambungan Chrome

<p>Saya perlu mentakrifkan Pekerja Perkhidmatan saya sebagai berterusan dalam sambungan Chrome kerana saya menggunakan API webRequest untuk memintas beberapa data yang dihantar dalam borang untuk permintaan tertentu, tetapi saya tidak tahu cara melakukannya. Saya telah mencuba segala-galanya tetapi Pekerja Perkhidmatan saya terus menyahpasang. </p> <p>Bagaimanakah saya memastikan ia dimuatkan dan menunggu sehingga permintaan dipintas? </p>
P粉323224129P粉323224129392 hari yang lalu590

membalas semua(2)saya akan balas

  • P粉034571623

    P粉0345716232023-08-25 17:51:37

    Tidak seperti chrome.webRequest API, chrome.webNavigation API berfungsi dengan sempurna kerana chrome.webNavigation API boleh bangun Service Worker, kini anda boleh cuba memasukkan chrome.webRequest API chrome.webRequest dalam API chrome.webRequest webNavigation.

    chrome.webNavigation.onBeforeNavigate.addListener(function(){
    
       chrome.webRequest.onResponseStarted.addListener(function(details){
    
          //.............
          
          //.............
    
       },{urls: ["*://domain/*"],types: ["main_frame"]});
    
    
    },{
        url: [{hostContains:"domain"}]
    });

    balas
    0
  • P粉386318086

    P粉3863180862023-08-25 00:41:03

    Daftar Kandungan

    • Penerangan masalah

    • Penyelesaian:

      • Eksploitasi
      离屏API
      nativeMessagingAPI
      WebSocketAPI
      chrome API Pemesejan
      • Tab khusus

    • Perhatian

    Secara takrifan, Pekerja Perkhidmatan (SW) tidak boleh diteruskan dan penyemak imbas mesti menamatkan semua aktiviti/permintaannya secara paksa selepas masa tertentu, iaitu 5 minit dalam Chrome. Pemasa tidak aktif (iaitu apabila tiada aktiviti sedemikian berlaku) adalah lebih pendek: 30 saat.

    Pasukan Chromium pada masa ini menganggap gelagat ini sebagai baik (pasukan kadang-kadang melonggarkan beberapa aspek, cth. Chrome 114 memanjangkan port chrome.runtime selepas setiap mesej), tetapi ini hanya terpakai pada sambungan yang memerhatikan peristiwa yang jarang berlaku, Acara ini adalah hanya berjalan beberapa kali sehari, sekali gus mengurangkan jejak memori penyemak imbas antara larian (cth. webRequest/webNavigation acara dengan url > penapisan untuk tapak yang jarang dilawati). Sambungan ini boleh direka bentuk semula untuk mengekalkan keadaan, Contoh. Malangnya, idyll seperti itu tidak dapat dikekalkan dalam banyak kes.

    Isu yang diketahui

    • Isu 1: Chrome 106 dan lebih awal tidak membangunkan perisian untuk acara webRequest.

      Walaupun anda boleh cuba melanggan API seperti chrome.webNavigation seperti yang ditunjukkan dalam jawapan lain, ia hanya membantu untuk acara yang berlaku selepas urutan pekerja dimulakan.

    • Masalah 2: Kakitangan secara rawak berhenti bangun kerana peristiwa.

      Penyelesaianmungkin dengan memanggil chrome.runtime.reload().

    • Isu 3: Chrome 109 dan lebih awal tidak boleh melanjutkan kitaran hayat perisian acara API chrome baharu daripada skrip latar belakang yang sudah dijalankan. Ini bermakna kod anda tidak akan dapat menjalankan apa-apa secara tidak segerak dengan pasti apabila peristiwa berlaku dalam beberapa milisaat terakhir daripada tamat masa tidak aktif selama 30 saat. Ini bermakna pengguna akan menganggap sambungan anda tidak boleh dipercayai.

    • Soalan 4: Prestasi akan lebih teruk daripada MV2 jika sambungan mengekalkan sambungan jauh atau keadaan (pembolehubah) mengambil masa yang lama untuk dibina semula, atau jika anda memerhatikan kejadian yang kerap seperti berikut:

      • chrome.tabs.onUpdated/onActivated,
      • chrome.webNavigation jika skop tidak terhad kepada URL yang jarang ditemui,
      • chrome.webPermintaan jika skop tidak terhad kepada URL atau jenis yang jarang berlaku,
      • chrome.runtime.onMessage/onConnect mesej untuk skrip kandungan dalam semua tab.

      Melancarkan SW untuk acara baharu pada asasnya seperti membuka tab baharu. Ia mengambil masa kira-kira 50 ms untuk mencipta persekitaran, mungkin 100 ms (atau 1000 ms, bergantung pada jumlah kod) untuk menjalankan keseluruhan skrip SW, dan mungkin 1 ms (atau 1000 ms, bergantung pada data) untuk membaca nyatakan daripada simpanan dan bina semula/hidratkannya) . Walaupun dengan skrip yang hampir kosong, ia mengambil masa sekurang-kurangnya 50 milisaat, yang merupakan overhed yang agak banyak untuk memanggil pendengar acara, yang hanya mengambil masa 1 milisaat.

      SW mungkin dimulakan semula ratusan kali sehari kerana peristiwa sedemikian dijana sebagai tindak balas kepada tindakan pengguna dengan jurang semula jadi, seperti mengklik tab dan kemudian menulis sesuatu, semasa perisian ditamatkan dan Acara baharu dimulakan semula, menggunakan CPU, cakera , bateri dan secara amnya memperkenalkan ketinggalan yang boleh dilihat dalam tindak balas penskalaan yang kerap.

    Mengeksploitasi pekerja perkhidmatan "berterusan" melalui ralat

    Chrome 110 memperkenalkan pepijat: memanggil sebarang asynchronous chrome API akan menyebabkan urutan pekerja berjalan selama 30 saat tambahan. Pepijat ini belum dibetulkan lagi.

    //background.js

    const keepAlive = () => setInterval(chrome.runtime.getPlatformInfo, 20e3);
    chrome.runtime.onStartup.addListener(keepAlive);
    keepAlive();
    

    Pekerja perkhidmatan "Tetap" dengan API luar skrin

    Disumbangkan oleh Kevin Augusto.

    Dalam Chrome 109 dan ke atas, anda boleh menggunakan API luar skrin untuk membuat dokumen luar skrin dan menghantar beberapa mesej daripadanya setiap 30 saat atau kurang untuk memastikan Pekerja Perkhidmatan berjalan. Pada masa ini, hayat dokumen tidak terhad (hanya main balik audio dihadkan, yang kami tidak gunakan), tetapi ini mungkin berubah pada masa hadapan.

    • manifest.json

        "permissions": ["offscreen"]
      
    • luar skrin.html

      <script src="offscreen.js"></script>
      
    • luar skrin.js

      setInterval(async () => {
        (await navigator.serviceWorker.ready).active.postMessage('keepAlive');
      }, 20e3);
      
    • background.js

      async function createOffscreen() {
        await chrome.offscreen.createDocument({
          url: 'offscreen.html',
          reasons: ['BLOBS'],
          justification: 'keep service worker running',
        }).catch(() => {});
      }
      chrome.runtime.onStartup.addListener(createOffscreen);
      self.onmessage = e => {}; // keepAlive
      createOffscreen();
      

    Sambung nativeMessaging Urutan pekerja perkhidmatan "berterusan" hos

    Dalam Chrome 105 dan ke atas, lalukan sahaja chrome.runtime.connectNative. Jika proses hos ditamatkan kerana ranap atau tindakan pengguna, port akan ditutup dan perisian akan ditamatkan seperti biasa. Anda boleh menghalangnya daripada memanggil chrome.runtime.connectNative sekali lagi dengan mendengar acara onDisconnect port.

    Urutan pekerja perkhidmatan "Tetap" semasa WebSocket aktif

    Chrome 116 dan ke atas: Bertukar mesej WebSocket setiap 30 saat untuk memastikan ia terus hidup, cth.

    Pekerja servis "Tetap" semasa tab boleh sambung wujud

    Keburukan:

    • Memerlukan tab web terbuka
    • Kebenaran hos luas untuk skrip kandungan (seperti *://*/*), yang akan meletakkan kebanyakan sambungan ke dalam baris gilir semakan perlahan kedai dalam talian

    Amaran! Jika anda mempunyai port yang disambungkan, jangan gunakan penyelesaian ini, gunakan penyelesaian lain untuk port di bawah.

    Amaran! Jika anda menggunakan sendMessage, anda juga boleh melaksanakan penyelesaian untuk sendMessage (di bawah).

    • manifest.json, bahagian yang berkaitan:

        "permissions": ["scripting"],
        "host_permissions": ["<all_urls>"],
        "background": {"service_worker": "bg.js"}
      
      
    • Pekerja perkhidmatan latar belakang bg.js:

      const onUpdate = (tabId, info, tab) => /^https?:/.test(info.url) && findTab([tab]);
      findTab();
      chrome.runtime.onConnect.addListener(port => {
        if (port.name === 'keepAlive') {
          setTimeout(() => port.disconnect(), 250e3);
          port.onDisconnect.addListener(() => findTab());
        }
      });
      async function findTab(tabs) {
        if (chrome.runtime.lastError) { /* tab was closed before setTimeout ran */ }
        for (const {id: tabId} of tabs || await chrome.tabs.query({url: '*://*/*'})) {
          try {
            await chrome.scripting.executeScript({target: {tabId}, func: connect});
            chrome.tabs.onUpdated.removeListener(onUpdate);
            return;
          } catch (e) {}
        }
        chrome.tabs.onUpdated.addListener(onUpdate);
      }
      function connect() {
        chrome.runtime.connect({name: 'keepAlive'})
          .onDisconnect.addListener(connect);
      }
      
    • Semua halaman sambungan lain seperti pop timbul atau pilihan:

      ;(function connect() {
        chrome.runtime.connect({name: 'keepAlive'})
          .onDisconnect.addListener(connect);
      })();
      

    Jika anda juga menggunakan sendMessage

    Dalam Chrome 99-101, anda perlu sentiasa memanggil sendResponse() dalam pendengar chrome.runtime.onMessage walaupun respons tidak diperlukan. Ini adalah pepijat dalam MV3. Selain itu, pastikan anda melakukan ini dalam masa 5 minit, jika tidak, hubungi sendResponse dengan segera dan hantar mesej baharu melalui chrome.tabs.sendMessage (ke tab) atau chrome.runtime.sendMessage (ke pop timbul) apabila kerja selesai.

    Jika anda sudah menggunakan port seperti chrome.runtime.connect

    Amaran! Jika anda turut menyambungkan lebih banyak port kepada pekerja perkhidmatan, anda perlu menyambung semula setiap port sebelum 5 minit berlalu, contohnya, dalam masa 295 saat. Ini adalah kritikal dalam versi Chrome sebelum 104, yang akan membunuh SW tidak kira berapa banyak port sambungan tambahan yang ada. Dalam Chrome 104 dan ke atas pepijat ini telah diperbaiki, tetapi anda masih perlu menyambungkannya semula kerana kitaran hayat 5 minit mereka tidak berubah, jadi penyelesaian paling mudah ialah menyambungkannya semula dengan cara yang sama dalam semua versi Sambungan Chrome: contohnya setiap 295 saat .

    • Contoh skrip belakang:

      chrome.runtime.onConnect.addListener(port => {
        if (port.name !== 'foo') return;
        port.onMessage.addListener(onMessage);
        port.onDisconnect.addListener(deleteTimer);
        port._timer = setTimeout(forceReconnect, 250e3, port);
      });
      function onMessage(msg, port) {
        console.log('received', msg, 'from', port.sender);
      }
      function forceReconnect(port) {
        deleteTimer(port);
        port.disconnect();
      }
      function deleteTimer(port) {
        if (port._timer) {
          clearTimeout(port._timer);
          delete port._timer;
        }
      }
    • Contoh skrip pelanggan, seperti skrip kandungan:

      let port;
      function connect() {
        port = chrome.runtime.connect({name: 'foo'});
        port.onDisconnect.addListener(connect);
        port.onMessage.addListener(msg => {
          console.log('received', msg, 'from bg');
        });
      }
      connect();
      

    "Sentiasa", melalui tab khusus, apabila tab dibuka

    Daripada menggunakan perisian, buka tab baharu dengan halaman sambungan di dalamnya, jadi halaman ini akan bertindak sebagai "halaman latar belakang yang boleh dilihat", iaitu satu-satunya perkara yang perlu dilakukan oleh perisian ialah membuka tab ini. Anda juga boleh membukanya daripada pop timbul tindakan.

    chrome.tabs.create({url: 'bg.html'})
    

    Ia akan mempunyai fungsi yang sama seperti halaman latar belakang berterusan ManifestV2, tetapi a) ia akan kelihatan dan b) tidak akan boleh diakses melalui chrome.extension.getBackgroundPage (boleh digantikan dengan chrome.extension.getViews).

    Keburukan:

    • menggunakan lebih banyak memori,
    • Membazir ruang dalam bar tab,
    • Ganggu perhatian pengguna,
    • Apabila berbilang sambungan membuka tab seperti ini, keburukan bola salji dan menjadi PITA sebenar.

    Anda boleh memudahkan pengguna dengan menambahkan maklumat/log/carta/papan pemuka pada halaman, dan juga menambah beforeunload pendengar untuk mengelakkan tab daripada ditutup secara tidak sengaja.

    Amaran tentang kegigihan

    Anda masih perlu menyimpan/memulihkan keadaan (pembolehubah) kerana tiada perkara seperti pekerja perkhidmatan yang berterusan dan penyelesaian ini mempunyai had seperti yang dinyatakan di atas supaya pekerja itu boleh ditamatkan perkhidmatan. Anda boleh mengekalkan keadaan dalam simpanan, Contoh.

    Sila ambil perhatian bahawa anda tidak seharusnya membuat rangkaian pekerja anda berterusan hanya untuk memudahkan pengurusan keadaan/pembolehubah. Ini hanya dilakukan untuk memulihkan prestasi yang lebih teruk dengan memulakan semula benang pekerja, sekiranya keadaan anda sangat mahal untuk dibina semula, atau jika anda terpengaruh dengan acara yang kerap disenaraikan pada permulaan jawapan ini.

    balas
    0
  • Batalbalas