2

I am writing a Chrome extension that needs to interact with urls that the user does not have open. Therefore I am using hidden iframes that are embedded within the popup, and am attempting to click a button within the iframe. However, I am receiving a same origin policy error. I know that it is possible for an extension to interact with iframes of a different domain via content scripts when the iframe is on the tab that the user has open, but I am not sure if it is possible to use content scripts to interact with iframes directly in the popup.

Here is my code:

manifest.json

"content_scripts": [


{
    "js": [ "bin/jquery.min.js", "interaction.js" ],
    "all_frames": true,
    "run_at": "document_start",
    "matches": [ "http://*/*",
                 "https://*/*" ]
  }],

  "permissions": [
    "activeTab",
    "tabs",
    "http://*/",
    "https://*/"
],

interaction.js

$(document).ready(function() {
  $('div#iframes').append("<iframe id='shop' src='https://www.google.com/'></iframe>")
  $('iframe').bind("load", function() {
    $('iframe').contents().find("html").ready(function() {
      loadedStores += 1;
      if (loadedStores == carts.totalStores) {
        $('div#cost').append(carts.grandTotal)
        showMain();
      }
    })
  })
})

Error

Uncaught SecurityError: Blocked a frame with origin "chrome-extension://mapgjiofchdchalgcifmdolgcekfaadp" from accessing a frame with    origin "https://www.google.com/".  The frame requesting access has a protocol of "chrome-extension", the frame being accessed has a protocol of "http". Protocols must match.

The error occurs in interaction.js in the third line (with the load callback). Does anyone know any changes I should make to the content script to allow me to interact with the iframe? Or if there are other approaches I should take? Thanks!

gmpatzer
  • 91
  • 1
  • 10
  • I updated it to include the error – gmpatzer Jul 02 '15 at 12:59
  • Why do you do it this way ? Why using old and horrible iframes ? You can't inject iframes like this because of chrome restriction. What you can do is to get thé content of your file and then add it inject it to your div – Emrys Myrooin Jul 02 '15 at 20:54
  • @EmrysMyrooin "Yeah, well, that's just, like, your opinion, man." What do you mean by "can't inject like this"? – Xan Jul 02 '15 at 21:49
  • @Xan I'm a litle upset about this subject because I'm working with this kind of things... So yes I don't have an impartial opinion about it. But, more seriously, there is lot of limitation about using iframes. First, when you send a message to a page with content scripts, you can't choose the targeted iframe. Second, you can't choose what iframes is targeted by a content script (at the moment because it apears that they are working on it). And you can't add an iframe in an existing page with a content that have not the same origin. – Emrys Myrooin Jul 03 '15 at 07:39

1 Answers1

1

Your frame will also have a content script injected.

You need to communicate with that content script using Messaging and make it do what you need.

Here's some further information:

Community
  • 1
  • 1
Xan
  • 74,770
  • 16
  • 179
  • 206
  • 1
    Is the content script actually injected in his case ? I mean, he append the iframe after the page loading. Does Chrome inject content script after page loading ? I have never tested this behavior – Emrys Myrooin Jul 03 '15 at 07:41
  • Yes, it will be injected. – Xan Jul 03 '15 at 17:42
  • Could you tell me how I would be able to do that? Other stack overflow questions like [this](http://stackoverflow.com/questions/8918133/inject-content-script-into-iframe-inside-background-html) say it's not possible. – gmpatzer Jul 04 '15 at 17:51
  • If your content script is defined in the manifest (with `"allFrames": true`), it should be injected. I just tested it. There may be difficulty in connecting _to_ it if you run it in the background page, but you can solve it by letting the content script initiate the connection. – Xan Jul 04 '15 at 17:52
  • My content script does have `"allFrames": true`. However, it is still running into the same origin policy. I'm running this on the popup window (the iframes), so am I missing something? – gmpatzer Jul 04 '15 at 18:32
  • Yes, you're missing something. You have 2 copies of your script: one in the original page, and one in the iframe. You need to pass a command from one to another. (BTW, as it's currently set up it's going to have infinite amounts of nested frames) – Xan Jul 04 '15 at 18:34
  • Can I pm or contact you? I'm a little confused on how to build chrome extensions (this is my first time). Thanks. – gmpatzer Jul 04 '15 at 19:11
  • I've tried that in the past, and didn't like it, so, no. As long as you [can formulate your questions](http://stackoverflow.com/help/how-to-ask), I'll be happy to help, as I'm monitoring the extensions tag. I've added a couple of further links that may help. – Xan Jul 04 '15 at 19:13
  • Your answer worked for the iframes, thank you for that. I was wondering what are some better options rather than iframes that can interact with a user's shopping cart in the background (without opening a tab and the user seeing the process). For example, a user clicks "remove for cart" in my plugin and the plugin would go to that website and remove the item from cart. – gmpatzer Jul 19 '15 at 19:45
  • It highly depends on the site in question. In many cases "remove from card" sends an AJAX request to the server; you could try and reverse-engineer that, and see if just requesting (but not loading in a frame) of that AJAX URL is sufficient. – Xan Jul 19 '15 at 19:48