I write codes below that popup.js, content.js and background.js. It can communicate popup.js <-> background.js. But content.js which is embedded in the site can't communicate background.js. Console.log in runtime.sendMessgae just say "undefine". How can I communicate background.js between content.js?
manifest.js
{
"manifest_version": 3,
"name": "test_project",
"short_name": "test",
"version": "1.0.0",
"description": "",
"action": {
"default_popup": "page/index.html"
},
"permissions": ["identity","scripting","storage","alarms"],
"content_scripts": [
{
"matches": ["file:///*"],
"js": [
"popup.bundle.js"
]
},
{
"matches": [ "*://mail.google.com/*" ],
"js": [
"content.bundle.js"
],
"run_at": "document_start"
}
],
"background": {
"service_worker": "background.bundle.js"
},
"oauth2": {
"client_id": "",
"scopes": [
"https://www.googleapis.com/auth/gmail.compose"
]
},
"web_accessible_resources": [{
"resources": [
"extension.bundle.js",
"extension.bundle.js.map",
"gmailJsLoader.bundle.js",
"gmailJsLoader.bundle.js.map"
],
"matches": ["<all_urls>"]
}],
"host_permissions": [
"https://*/*"
],
"options_page": "page/options.html"
}
background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log('π₯ λ©μμ§ μμ :', request);
if (request.action === 'getAuthToken') {
console.log('π getAuthToken νΈμΆ μμ');
chrome.identity.getAuthToken({ interactive: true }, (token) => {
if (chrome.runtime.lastError) {
console.error('β μ€λ₯ λ°μ:', chrome.runtime.lastError);
sendResponse({ success: false, error: chrome.runtime.lastError.message });
} else {
console.log('β
μ‘μΈμ€ ν ν°:', token);
sendResponse({ success: true, token });
}
});
// λΉλκΈ° μλ΅μ λκΈ°
return true;
}
});
popup.js
// It can work
document.getElementById('inesrtAddressBookButton').addEventListener('click', () => {
chrome.runtime.sendMessage(EXTENSION_ID, { action: 'getAuthToken' }, (response) => {
console.log(response)
})
})
content.js
// It loaded on gmail
const loaderId = setInterval(() => {
if (!window._gmailjs) {
return;
}
clearInterval(loaderId);
startExtension(window._gmailjs);
}, 100);
function startExtension(gmail) {
console.log("Extension loading...");
window.gmail = gmail;
gmail.observe.on("load", () => {
gmail.observe.on("compose", (compose) => {
var content_html = $(`
<div>
test
</div>
`);
gmail.tools.add_compose_button(compose, content_html, function() {
getAuthTokenAndFetchData(compose)
}, "");
});
});
}
function getAuthTokenAndFetchData(compose) {
chrome.runtime.sendMessage(EXTENSION_ID, { action: 'getAuthToken' }, (response) => {
console.log(response)
})
}
Judging by the fact that you access page variables on window
, the code runs in a DOM script
element or in an explicitly specified MAIN
world (more info). The script is no longer a part of the extension's context, but just an unprivileged web page script without access to chrome
global API that only exists in the isolated content script.
To send a message to the extension you need to use externally_connectable
messaging: https://developer.chrome.com/docs/extensions/develop/concepts/messaging#external-webpage
Note that you don't need it in the chrome-extension:// pages such as the action
popup, so you can remove EXTENSION_ID in your popup.js that runs in the page specified as default_popup
.