Chrome extension contentscripts inside IFrames, inside the backgroundpage
Reported by
bugs.chr...@eigenvektor.de,
May 9 2017
|
|||||
Issue descriptionUserAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/58.0.3029.81 Chrome/58.0.3029.81 Safari/537.36 Steps to reproduce the problem: (I wanted to post under component=Platform>Extensions, but that option isn't available. Someone please move this feature request there.) I'm working on a Chrome extension that needs contentscripts inside IFrames inside the backgroundpage. Also I don't want to use the <all_urls> permission. I want to request only the needed host-permissions at runtime. I can't find a way to do both. Here [1] are the two ways to declare contentscripts. [1] https://developer.chrome.com/extensions/content_scripts The problem with the manifest file is: I can't specify a match-pattern, because I don't know the hosts, and I don't want to use the <all_urls> match-pattern. The problem with the programmatic injection is: The backgroundpage doesn't have a tabId. Without it I can't use chrome.tabs.executeScript. My suggestion is to add another match pattern like this. "content_scripts": [ { "matches": ["<all_urls_with_host_permission>"], "js": ["myscript.js"] } ] This pattern should match all urls that my extension has the host permission for. What is the expected behavior? What went wrong? n/a Did this work before? N/A Does this work in other browsers? N/A Chrome version: 58.0.3029.81 Channel: n/a OS Version: 4.4.0-75-generic Flash Version: Shockwave Flash 24.0 r0
,
May 12 2017
Hmm...
"content_scripts": [
{
"matches": ["<all_urls_with_host_permission>"],
"js": ["myscript.js"]
}
]
Why is this different than just copying the hosts from your host permissions?
,
May 12 2017
I think it'd be better if we could specify an iframe element directly in chrome.tabs.executeScript instead of tabId (absent for non-tab extension pages) and frameId (pretty useless except in very specific cases) parameters.
,
May 12 2017
> I think it'd be better if we could specify an iframe element directly in chrome.tabs.executeScript instead of tabId (absent for non-tab extension pages) and frameId (pretty useless except in very specific cases) parameters. By "specify an iframe element directly", are you envisioning something like: // background.html <html> <body> <iframe src="example.com" id="example-iframe"></iframe> </body> <script src="background.js"></script> </html> // background.js var iframe = document.getElementById("example-iframe"); chrome.tabs.executeScript(iframe, {code: 'console.warn("injected!")'}); ? If so, that's an interesting thought. Unfortunately, it doesn't play very nicely with the current implementation of the executeScript function (in chrome internals). We could probably find a way of supporting it, but it would be a little complicated, and probably isn't something we'll be able to get to in the near future. It also has some other problems around race conditions if you care about injection timing. We tried to solve this with <webview> [1], but I don't think that's exposed to extensions. [1] https://developer.chrome.com/apps/tags/webview#method-addContentScripts
,
May 12 2017
Yes, that's what I thought. As for webview, the primary reason it's not exposed for extensions IIRC was that extensions can do everything it provides using the alternative methods. This bug report shows that's not entirely true so maybe exposing webview for extensions would be a simpler solution?
,
May 13 2017
> Why is this different than just copying the hosts from your host permissions? I don't know them when I write the manifest. I want to ask the user for permissions at runtime. I think my suggestion probably boils down to a simple if/else. I haven't seen the Chromium source, but I imagine it's something like this. First check if the pattern is <all_urls>. If that fails, check if the pattern matches the url. If that fails, then don't inject the contentscript. Just add an additional check at the end: has the user granted a host permission for this url (either at runtime, or in the manifest)? If yes, then inject the contentscript.
,
May 15 2017
@5 Given webview is pretty non-standard and has caused some issues lately with things like site isolation, I'm not sure we necessarily want to expand its usage. But I agree it's kind of strange to not have a solution to this issue. There are a few other possible solutions here - as you have mentioned, we could take an iframe element directly (though this involves some fun renderer logic), or we take some other form of identification (I think that each frame now has a unique frame tree node, so we could obviate tab id), or event just assign a unique non-positive tab id to the background page (e.g., introduce a chrome.tabs.BACKGROUND_PAGE_TAB_ID constant that could be passed to chrome.tabs.executeScript). The last option may be the simplest from both the platform and usage standpoints; would that address all the concerns? @6 It's not quite that simple, since sometimes you don't want to inject content scripts on a page even if you have permission. e.g., you might want to be allowed to inject on every site with some user action, but by default inject some script on example.com and google.com. Can you also elaborate a bit on the use case here, so we have a better idea of the motivation? (typically, injecting scripts into a page that isn't visible to the user is unnecessary)
,
May 15 2017
Sorry, I wasn't very precise. For each contentscript you have a match-pattern in the manifest. At some point Chromium has to decide if it injects a contentscript into a website or not, with the help of this match-pattern. Add an additional check before Chromium finally rejects: Is the match-pattern for this contentscript <all_urls_with_host_permission>, and has the user granted a host permission for this website (either at runtime, or in the manifest)? If yes, then inject the contentscript. This way nothing changes if you don't use <all_urls_with_host_permission> as a match-pattern for a contentscript in your manifest. Giving the backgroundscript a tab-id in regard to executeScript should also work. To elaborate on a use case. I'm working on a download manager for image galleries. I want to skip all the preview/thumbnail pages with it. Therefor I have to read the links from a number of subpages. It works fine with xhr from the backgroundscript, but only when the links are not generated with javascript as the subpages are rendered. I need IFrames for that, and I would rather put them in the backgroundscript.
,
May 15 2017
AFAIK scraping an AJAX-driven web site is quite a common use case for the background iframe with a content script.
,
May 15 2017
There are two points: (1) I'm working on a Chrome extension that needs contentscripts inside IFrames inside the backgroundpage. (2) Also I don't want to use the <all_urls> permission. I want to request only the needed host-permissions at runtime. I can't find a way to do both (1) and (2) at the same time.
,
May 15 2017
If the idea of a background-page tab id works, I think that's the preferable solution due to its simplicity and determinism. Doing that sounds pretty reasonable to me. The idea of a <all_urls_with_host_permission> is feasible, but it's a little more complex and less predictable. This should be pretty doable, but it's probably not something we can get to immediately. cc'ing some other folks in case they want to jump on it. To help us prioritize this with other requests, if there's anyone else interested in this feature, please star the bug.
,
Feb 8 2018
|
|||||
►
Sign in to add a comment |
|||||
Comment 1 by krajshree@chromium.org
, May 10 2017Labels: -Type-Bug M-60 Type-Feature
Status: Untriaged (was: Unconfirmed)