Fredthedoggy
Fredthedoggy

Reputation: 351

Custom User Agent with Iframes

Yes, I have read Load iframe content with different user agent but I do not understand how to implement it correctly/it does not work

I am trying to create a Iframe with a custom user agent inside a chrome extension, and this is my current code (from other tutorials/answers)

function setUserAgent(window, userAgent) {
    if (window.navigator.userAgent != userAgent) {
        var userAgentProp = { get: function () { return userAgent; } };
        try {
            Object.defineProperty(window.navigator, 'userAgent', userAgentProp);
        } catch (e) {
            window.navigator = Object.create(navigator, {
                userAgent: userAgentProp
            });
        }
    }
}
window.addEventListener("load", function() {
document.querySelector('iframe').contentWindow, 'Test User Agent';
});
<title>Title</title>
<link rel="icon" href="favicon.ico" type="image/ico" sizes="16x16">
<iframe src="https://www.whatsmyua.info/" frameborder="0" style="overflow:hidden;height:100%;width:100%" height="100%" width="100%"></iframe>
<script src='index.js'>
</script>

For Some reason the user agent is not working, as shown by the page that loads.

Upvotes: 2

Views: 1740

Answers (1)

woxxom
woxxom

Reputation: 73616

You need to insert that code into the page context using a content script.

1a. Inject a content script

It can be injected programmatically from your extension page into the iframe.

manifest.json

"permissions": ["webNavigation"]

index.js:

chrome.tabs.getCurrent(tab => {
  chrome.webNavigation.onCommitted.addListener(function onCommitted(info) {
    if (info.tabId === tab.id) {
      chrome.webNavigation.onCommitted.removeListener(onCommitted);
      chrome.tabs.executeScript({
        frameId: info.frameId,
        file: 'content.js',
        runAt: 'document_start',
      });
    }
  }, {
    url: [{urlEquals: document.querySelector('iframe').src}],
  });
});

1b. Declare a content script

Note that the previous approach may theoretically allow some of the iframe's inline scripts in its <head> to run first. In that case you'll have to add a dummy URL parameter to the iframe src (for example https://example.org/page/page?foobar) and use declarative matching in manifest.json:

"content_scripts": [{
  "matches": ["*://example.org/*?foobar*"],
  "all_frames": true,
  "run_at": "document_start",
  "js": ["content.js"]
}],

2. Add a page script

To run our code immediately let's run it via textContent. We're not using a separate file for page code because that would put it into a queue where it could run after the currently pending page scripts.

content.js:

var script = document.createElement('script');
script.textContent = '(' + function() {
  Object.defineProperty(navigator, 'userAgent', {
    get() {
      return 'Test User Agent';
    },
  });
} + ')();';
(document.head||document.documentElement).appendChild(script);
script.remove();

Upvotes: 1

Related Questions