はじめに
####MV3で何が変わるの、か?
Chromeオフィシャルサイトによると大まかには以下が変更点という、ことらしい。
機能の概要
- サービスワーカーによるバックグラウンドページの置き換え。
- ネットワークリクエストの変更は、declarativeNetRequestAPIで処理される。
- リモートでホストされたコードは許可されず、パッケージに含まれているJavaScriptのみを実行可能。
- 多くのメソッドにPromiseのサポートを追加。
えーっと、、とりあえずわかったふりをしつつ、、。
やってみよう
今回MV3に移行するExtensionsでは、バックグラウンド処理としてはコンテキストメニューのみ。ただ、formをDOM生成してPOST送信している。だが、DOMは扱えない、んだ。
####どうするのか?
解決策としては2つ。
- 個人情報は扱ってなく、受信側もPOST・GET両方に対応させてるので、GET送信に変更。
- 新しくTabページを開いてPOST送信。
> まずは、
manifest.json
の更新
{
- "manifest_version": 2,
+ "manifest_version": 3,
...
- "browser_action": {
+ "action": {
"default_icon": {
"16": "img/icon16.png",
"32": "img/icon32.png",
"48": "img/icon48.png",
"128": "img/icon128.png"
},
"default_title": "__TITLE__",
"default_popup": "popup.html"
},
- "content_scripts": [
- {
- "matches": [ "http://*/*", "https://*/*" ],
- "js": [ "js/jquery-3.6.0.min.js", ... ]
- }
- ],
"permissions" : [
"activeTab",
- "contextMenus",
+ "contextMenus"
- "http://*/*",
- "https://*/*"
],
+ "host_permissions": [
+ "http://*/*",
+ "https://*/*"
+ ],
"background": {
- "scripts": [ "background.js" ],
- "persistent": false
+ "service_worker": "background.js"
}
}
content_scripts
の理解が出来てなく、パッケージ内で使用してるjs
を全て書いていたので削除しました。
> バックグラウンド処理
######GETで送信
に変更する場合
chrome.contextMenus.removeAll(function() {
chrome.contextMenus.create({
id: '__ID__',
title: '__TITLE__',
contexts: ['image', 'video'],
type: 'normal'
});
});
chrome.contextMenus.onClicked.addListener(function(info, tab) {
if (info.menuItemId == '__ID__') {
- var frm = document.createElement('form');
- frm.setAttribute('method', 'POST');
- frm.setAttribute('target', '_blank');
- frm.setAttribute('action', '__URL__');
- var req = document.createElement('input');
- req.setAttribute('type', 'hidden');
- req.setAttribute('name', 'img_url');
- req.setAttribute('value', info.srcUrl);
- frm.appendChild(req);
- document.body.appendChild(frm);
- frm.submit();
+ chrome.tabs.create({ url: '__URL__?img_url=' + info.srcUrl });
}
});
GETメソッドで扱えるデータに上限があるので、今回はPOSTを選択。
######POSTで送信
する場合
chrome.contextMenus.removeAll(function() {
...
});
chrome.contextMenus.onClicked.addListener(function(info, tab) {
if (info.menuItemId == '__ID__') {
- ...
+ postForm('__URL__', {'img_url': info.srcUrl});
+
+ function postForm(url, data) {
+ chrome.tabs.create(
+ { url: chrome.runtime.getURL('postform.html') },
+ function(tab) {
+ var handler = function(tabId, changeInfo) {
+ if(tabId == tab.id && changeInfo.status == "complete"){
+ chrome.tabs.onUpdated.removeListener(handler);
+ chrome.tabs.sendMessage(tabId, {url: url, data: data});
+ }
+ }
+ chrome.tabs.onUpdated.addListener(handler);
+ chrome.tabs.sendMessage(tab.id, {url: url, data: data});
+ }
+ );
+ }
}
});
新しくTabページを開き、ServiceWorkerとページ間でメッセージのやり取りが可能なので、開いたページ(postform.html
)にdata
を渡します。
<html><body><script src="js/postform.js"></script></body></html>
開いたページではDOM操作が可能だが、インラインJavaScriptは書くことが出来ないので注意が必要です。
var onMessageHandler = function(message){
chrome.runtime.onMessage.removeListener(onMessageHandler);
var frm = document.createElement('form');
frm.setAttribute('method', 'post');
frm.setAttribute('action', message.url);
for(var key in message.data) {
var req = document.createElement('input');
req.setAttribute('type', 'hidden');
req.setAttribute('name', key);
req.setAttribute('value', message.data[key]);
frm.appendChild(req);
}
document.body.appendChild(frm);
frm.submit();
}
chrome.runtime.onMessage.addListener(onMessageHandler);
メッセージを受け取ったらformをDOM生成しPOST送信。
まとめ
バックグラウンドでDOMが扱えなくなった、んだ。どうにかDOMを扱うことは出来ないのか?、、fake-domのようなもので代替出来ないのか?、、、、試行錯誤し、、模索し、あきらめかけましたが、、新しく開いたページではDOM操作が可能という事だったので、MV2と同じ機能のままMV3に移行することが出来ました。
今回MV3に移行したChrome Extensions