10

Can anyone post the code for accessing the window variables in chrome extension. I need to access the window variables when i click the chrome extension button. I am getting the window object, but not with all the variables loaded. I know we can create it by injecting the script. But i am not getting how to achieve it. Currently I am trying the following code to get the page source of the current active tab.

 chrome.tabs.executeScript({code:
            "document.getElementsByTagName('html')[0].innerHTML"
        }, function(result) {
    var value = result[0];
    console.log(value);
    chrome.tabs.query({currentWindow: true, active: true}, function(tabs) {
        callback({
            url: tabs[0].url,
            title: tabs[0].title,
            jsonValue: value
        });
    });
}); 

Please help me in solving this issue. It would be highly appreciated.

Srinivas B
  • 1,821
  • 4
  • 17
  • 35
  • What are you getting now with this script ? When it is executed ? – Emrys Myrooin Sep 18 '15 at 07:12
  • @EmrysMyrooin, I am getting the page source of the current tab. But instrad of this i need to get all the window variables in the page source – Srinivas B Sep 18 '15 at 07:14
  • So why don't you simply return the `window` object ? like `chrome.tabs.executeScript({code: "window" }, function(result) { ... })` I didn't try it but there is no reason to not work :-) – Emrys Myrooin Sep 18 '15 at 07:16
  • And if the question is how to get all _javascript_ vraiables of the source page, the official Google answer is : you can't. But I don't think that is what you want. – Emrys Myrooin Sep 18 '15 at 07:18
  • Okey forget about this. There is no simple solution to send the `window`variable. The reason is that it contains circular references that is not representible in JSON format. So the better solution you have is to extract the wanted values from `window` object and then only send back this extracted values. Or You can try to use an other format than JSON to represent your data, but for this you have to inject an external library... – Emrys Myrooin Sep 18 '15 at 07:51
  • thanks @EmrysMyrooin. I tried returning the window object with jsonValue: window. It was fetching the window object, without the window variables. Also I tried with jsonValue: window.appData, which is the variable I want to retrieve. Again the same result with undefined. Could you suggest me a possible way. Your help would be appreciated. – Srinivas B Sep 18 '15 at 08:19
  • Humm what is appData ? It's not an attribute of the `window` object – Emrys Myrooin Sep 18 '15 at 08:44
  • Its the JSON object configured in the script – Srinivas B Sep 18 '15 at 08:49
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/90001/discussion-between-srinivas-b-and-emrys-myrooin). – Srinivas B Sep 18 '15 at 08:50
  • Ok go to the chat room – Emrys Myrooin Sep 18 '15 at 08:56
  • This question was many times given and answered, see the awesome answer in the duplicate - in short: it's not the code you quoted in your question. – wOxxOm Sep 18 '15 at 09:41

1 Answers1

20

What you are asking for is to inject a script an get the value of a variable defined in the original page script. There are two answers to this problem:

1. Official Google answer

This is not possible. Content script injected in a page is sandboxed and can't access to original page javascript scope. This means that you can't access to variable, function and objects defined in the original page's javascript. And your variable, function and objects will not be accessible from the original page.

Only the DOM of the page is shared. That allow you to modify the content of the page. But you can't, for example, delete an existing event handler.

This is for evident security and safety reason. If you override without knowing it a function of the original page, it would break it.

Take a look here for more information

2. Unofficial and dirty answer

There is a way to bypass the chrome sand box restriction. This come with the shared DOM that allow you to add a <script src="..."><\script> to the page. The script will be loaded and executed in the original page's javascript VM so you will have access to the global javascript scope.

But this way, will not have access to the Chrome extension API, because you are running code in the original page. So the communication with the background page or the injected Content Script will be difficult.

A common way to do this is to add a hidden <div> to the page and put in it the result you want to send to your Content Script. You put the result as text (with JSON.stringify for example) and then read the result with your Content Script.

It's really dirty and it have to be use only in last try.

Community
  • 1
  • 1
Emrys Myrooin
  • 2,179
  • 14
  • 39
  • or sending messages back and forth between plugin and main page javascript, ex: http://stackoverflow.com/a/9636008/32453 – rogerdpack Oct 18 '16 at 22:03
  • 3
    This answer is **wrong**. There's no need for the dirty solution at all. The official Google way supports `window.postMessage`. See https://developer.chrome.com/extensions/content_scripts#host-page-communication – Pacerier Feb 21 '17 at 12:39
  • 2
    @Pacerier The answer is correct for a very precise question. This answer has been made to answer "Can I get window attributes of the host page ?". In his case, he doesn't have access to the source of the host page. He can't modify the main JavaScript of the host page, so he can't make any comunication between the main script and the extension (at least without the dirty hack). – Emrys Myrooin Feb 21 '17 at 14:11
  • @EmrysMyrooin, You still don't get it.. The "dirty" shared DOM is not the only way; that is why I said use `window.postMessage` which allows communication. So u take the variable `x`, and you pass it through `window.postMessage(x, '*')`, and your injected content script will be able to read the variable `x` by listening on `window.addEventListener("message", (e) => console.log(e.data))`. No DOM hacks needed. You can pass data from the content script to the webpage the same way. – Pacerier Feb 21 '17 at 22:49
  • 2
    These comments are super useful! I agree with @Pacerier that `window.postMessage` is the proper way of doing things here, but inserting a script has been super useful for me, too.. in my case, I want to log to the original window's console, which I've achieved by inserting a script into the page as @Emrys has described... gold! – ptim Oct 16 '17 at 23:20