问题
I have a chrome extension where a user inputs some information and it generates a report. Now of course, this report will be different each time based on what the user has entered.
What I want to achieve, is for my extension to say:
Hey, Mr. Background page. Here's the information you need, now build some html based off what I've given you and show it to the user.
Here is the manifest.json
that I'm using:
{
"manifest_version": 2,
"name": "XXXX",
"description": "XXXX",
"version": "1.0.0",
"permissions": ["storage", "tabs"],
"options_page": "settings.html",
"background":
{
"page": "background.html"
},
"content_scripts":
[
{
"matches": ["<all_urls>"],
"js": ["js/jquery-3.1.1.min.js", "js/bootstrap.min.js", "js/main.js", "js/background.js"],
"css": ["css/bootstrap.min.css", "css/font-awesome.min.css"]
}
],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"icons": { "128": "logo.png" }
}
Here is my background.html
<html>
<body>
<script src="js/jquery-3.1.1.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/background.js"></script>
</body>
</html>
And here is my background.js
$(document).ready(function() {
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
$("body").html(msg.message);
console.log("Message from: " + msg.message);
});
});
Now, when the user clicks a button on my extension, I use the following code to send message:
$("#generate").click(function() {
chrome.tabs.create({url: 'background.html'});
chrome.runtime.sendMessage({
message: "Sample message."
});
});
Now what I expected to happen, was for my background.html
page to open and then have the body of the page change based on what message was sent, but this does not work.
Any ideas?
回答1:
You are making a huge conceptual mistake by trying to use the same page for the background and to display something. This can lead to very unpredictable behavior.
You are essentially trying to open a tab with background.html
and somehow expect it to be "that same" background page. It doesn't work like that - you're opening a new instance of the same document. Think opening the same web form in two tabs - you don't expect them to mirror text entered into fields.
On top of that, a lot of mistakes are piled on in respect to popup pages' interaction with opening tabs.
So, the plan of action:
If you really need for a piece of code to execute in a (permanently invisible) background page, call it idiomatically
background.js
and switch toscripts
-style background page definition:"background": { "scripts": ["background.js"] }
Also, consider using Event pages.
Whatever you use for report-showing should not be called
background
for your sanity's sake. Rename itreport.html
/report.js
.In your popup code, your mistake #1 is timing. You open a page that ought to listen for your message, but do not wait for it to become ready to listen. You should use the callback of
tabs.create
if you want to make sure the page is actually open and ready.chrome.tabs.create({url: "report.html"}, function(tab) { // Okay, now it's ready, right? Right?.. chrome.runtime.sendMessage(/*...*/); });
However, doing that won't solve the problem, since opening a new tab by default focuses it (which is something you want, presumably), which immediately forces the popup to close. There is nothing you can do to prevent it as soon as a tab is focused. But that means your message is not going to be sent: popup will be destroyed before it happens.
So, don't rely on messaging. Presumably, you can store whatever data your report is based on in storage. So, set it first, then open the report page, where you read the data and build the report.
// Popup chrome.storage.local.set({foo: bar}, function() { // Storage is updated, it's showtime! chrome.tabs.create({url: "report.html"}); // And now, we die, inevitably. Goodbye, cruel world. }); // Report chrome.storage.local.get("foo", function(data) { // Oh, what joy is to have data.foo in here! });
来源:https://stackoverflow.com/questions/40173752/send-message-to-background-page-update-the-html-and-then-show-it-in-a-tab