0

I'm working on a Chrome extension which is supposed to gather some form data from a webpage and it's iframe. The challenge is that not all form data is immediately available in the iframe, but it appears only when a script is run. For some reason I'm not able to call for the script, and I cannot figure out why. The pages are on the same site.

I'll try to demonstrate the situation with the following pieces of code. There, the script in the iframe page just changes the content of the form field.

index.html (the webpage)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>

<h1>INDEX1.HTML</h1>
<iframe id="iframe1" src="index2.html" style="width: 800px; height: 600px; border: 1px solid #aaa"></iframe>
<p><input id="input1" type="text" value="XYZ" /></p>

</body>
</html>

The form field on this page is easily accessed from the extension.

index2.html (the iframe page)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<script>
function changeInput (n) {
    if (n == 1) document.getElementById('input2').value = 'ABC';
    else document.getElementById('input2').value = '123';
}
</script>
<body>

<h1>INDEX2.HTML</h1>
<p><button onclick="changeInput(1)">ABC</button>
<button onclick="changeInput(2)">123</button></p>
<p><input id="input2" type="text" value="ABC" /></p>

</body>
</html>

Clicking the buttons change the value of the form field. I cannot start the script from the extension, though, and that's the problem.

manifest.json

{
  "name": "Iframe-test",
  "version": "1.0",
  "manifest_version": 2,
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"],
      "all_frames": true
    }
  ],
  "browser_action": {
    "default_title": "Iframe-test",
    "default_popup": "popup.html"
  },
  "permissions": [ "tabs", "activeTab" ],
  "icons": { "16": "icon16.png",
      "32": "icon32.png",
      "48": "icon48.png",
      "128": "icon128.png" }
}

popup.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="popup.js"></script>
</head>
<body>

<p><input type="text" id="first" /></p>
<p><input type="text" id="second" /></p>
<p><input type="text" id="third" /></p>

</body>
</html>

The extension popup page with the fields to be filled with the gathered data.

popup.js

window.onload = function () {
    chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) {
        chrome.tabs.sendMessage(tabs[0].id, null, function (response) {
            document.getElementById('first').value = response.value1;
            document.getElementById('second').value = response.value2;
            document.getElementById('third').value = response.value3;
        });
    }); 
};

The script ran once the popup is opened.

content.js

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    val1 = document.getElementById('input1').value;
    val2 = document.getElementById('iframe1').contentWindow.document.getElementById('input2').value;
    document.getElementById('iframe1').contentWindow.changeInput(2);
    val3 = document.getElementById('iframe1').contentWindow.document.getElementById('input2').value;
    sendResponse({ value1: val1, value2: val2, value3: val3 });
});

Val1 is gathered fine, as is val2. But then, the script doesn't run, and val3 cannot be reached, and the whole thing fails. When I enter these lines in the console log, they work OK.

I bet this must be possible, and there's just a tiny issue somewhere, which I just don't know, see, or understand. Please point it out for me. Thanks a lot!

Community
  • 1
  • 1
Essen
  • 101
  • 1
  • 1
    Content scripts can't directly access functions defined in the *page context*. You need to [Insert code into the page context using a content script](https://stackoverflow.com/a/9517879) and that code will be able to call page functions. – wOxxOm Mar 24 '20 at 12:32

1 Answers1

-1

CORS stands for Cross-Origin Resource Sharing

CORS prevents code from access to something of a different origin An origin is the source from where code is running from. For example, the origin of this page is https://stackoverflow.com/questions/60831083/how-to-run-a-script-in-an-iframe-from-an-extension and if I make a request to https://github.com CORS would block it.

As a solution you can run a version of chrome without CORS and all should run smoothly.

To run such a version, go into Command Prompt and type "location\for\chrome" --disable-web-security --disable-gpu --user-data-dir=~/chromeTemp

The Bomb Squad
  • 4,192
  • 1
  • 9
  • 17
  • Not applicable to extensions as their content scrips run in a special "isolated world". The OP already has content scripts running in iframes due to `"all_frames": true` so it's not a problem, this answer has missed the point. – wOxxOm Mar 24 '20 at 17:31