chrome插件将js直接注入頁面有兩種方式,一種是通過manifest檔案中指定js檔案,一種是通過chrome.tab.executescript方式注入。具體可以參考這個官方文檔。
由于各種需求,需要将部分js從後端伺服器中進行加載。是以隻能通過tab.executescript的方式。具體函數的定義,可以參考官方文檔。大緻就是能夠給定一個檔案或者一段代碼,在指定的tab中運作。
首先,這個函數必須在background中執行,頁面中的content-script本身,是沒有權限調用chrome.tab api的。是以,如果頁面中的js要執行,需要通過chrome插件的通信機制(port, message),通知background才能運作。
其次,運作的目标tab,可以指定,也可以傳null,如果目标tab為null,則表示需要執行的tab是“目前tab”。是以如果使用了null,則在注入前千萬不能換tab,否則就注入到其他tab中去了。
然後,參數injectdetails中可以指定是執行code,還是file。如果是file,可以是本地檔案(插件中打包的檔案),也可以是遠端檔案。特别注意,通過file執行遠端檔案,有着嚴格的限制(參照這裡):‘currently, we allow whitelisting origins with the following schemes: https, chrome-extension, and chrome-extension-resource.’也就是說,隻能執行插件内部打包的檔案,或者基于https的遠端位址。其他還有例外的就是給開發者用的localhost了。我們要加載的資源,不可能放在本地,也不可能打包到插件中,也沒有辦法去搞到https的證書。是以不能通過執行file的方式加載遠端js。
要解決這個問題,隻能通過執行code的方式。由于我們在manifest檔案中配置了background擁有跨域請求資源的權限,我們可以直接在background中,遠端通過xhr的方式擷取js内容,然後進行code的執行。這樣就能繞開之前遇到的無法執行http協定的js檔案的問題。大緻的代碼如下:
最後,還有一個小問題,就是injectdetails中的allframes參數。這個參數大緻的作用,就是如果為true,js會在頁面的所有frame中進行執行,否則就隻在頁面的top frame中進行執行。由于frame之間的document會互相隔離,所有如果要讓frame之間能夠通信,就需要設定成true,把代碼注入到所有的frame中去。
轉載自:https://coolex.info/blog/424.html