I am developing a Chrome extension for work, and one of the things it needs to do is to read (only read, not modify) an object that we send back to the website after it makes an asynchronous request to our servers. Basically I need to read the window.<our object name>
object and get what's in there.
Now, I know this is possible, because I did this in a Tampermonkey script that I wrote. I was able to console.log(window.<our object name>)
and it came in.
Tampermonkey is a Chrome extension, so there's no intrinsic reason why it can access something and another extension can't.
But when I try to access this object, both from content scripts and from injected code, I get nothing. When I get the window
object only, it es up only partially, as if the extension were blind to certain parts of it. But if I'm in the console on the page, and I call window
, I get a full window object back. Infuriating.
So if content scripts don't work, and injected scripts don't work, and there's no reason why popup scripts would be any good here, how does one do this?
Many thanks!
UPDATE: As requested, here is the manifest.json (I took the page_redder example and worked off that to make sure I wasn't making any weird mistakes):
{
"name": "Page Redder",
"description": "Make the current page red",
"version": "2.0",
"permissions": [
"activeTab"
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_title": "get my object"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"manifest_version": 2
}
And here is content.js:
var getWindow = window.setTimeout(function() { console.log("From content script: " + window.<OBJECT NAME>); }, 5000);
And here is background.js:
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Called when the user clicks on the browser action.
chrome.browserAction.onClicked.addListener(function(tab) {
// No tabs or host permissions needed!
chrome.tabs.executeScript({
code: 'console.log("From injected script:" + window.<OBJECT NAME>);'
});
});
When run, I get:
From content script: undefined From injected script: undefined
But if I do window. from the console, I get it. I even added a timeout to make sure that the content script wasn't trying to get something that hadn't loaded in yet. But I can retrieve the object manually before the script runs, and it still gives me undefined.
I am developing a Chrome extension for work, and one of the things it needs to do is to read (only read, not modify) an object that we send back to the website after it makes an asynchronous request to our servers. Basically I need to read the window.<our object name>
object and get what's in there.
Now, I know this is possible, because I did this in a Tampermonkey script that I wrote. I was able to console.log(window.<our object name>)
and it came in.
Tampermonkey is a Chrome extension, so there's no intrinsic reason why it can access something and another extension can't.
But when I try to access this object, both from content scripts and from injected code, I get nothing. When I get the window
object only, it es up only partially, as if the extension were blind to certain parts of it. But if I'm in the console on the page, and I call window
, I get a full window object back. Infuriating.
So if content scripts don't work, and injected scripts don't work, and there's no reason why popup scripts would be any good here, how does one do this?
Many thanks!
UPDATE: As requested, here is the manifest.json (I took the page_redder example and worked off that to make sure I wasn't making any weird mistakes):
{
"name": "Page Redder",
"description": "Make the current page red",
"version": "2.0",
"permissions": [
"activeTab"
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_title": "get my object"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"manifest_version": 2
}
And here is content.js:
var getWindow = window.setTimeout(function() { console.log("From content script: " + window.<OBJECT NAME>); }, 5000);
And here is background.js:
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Called when the user clicks on the browser action.
chrome.browserAction.onClicked.addListener(function(tab) {
// No tabs or host permissions needed!
chrome.tabs.executeScript({
code: 'console.log("From injected script:" + window.<OBJECT NAME>);'
});
});
When run, I get:
From content script: undefined From injected script: undefined
But if I do window. from the console, I get it. I even added a timeout to make sure that the content script wasn't trying to get something that hadn't loaded in yet. But I can retrieve the object manually before the script runs, and it still gives me undefined.
Share Improve this question edited Apr 17, 2016 at 7:24 StormShadow asked Apr 17, 2016 at 5:21 StormShadowStormShadow 1,6274 gold badges26 silver badges34 bronze badges 6-
Can you include
javascript
,manifest.json
at Question? – guest271314 Commented Apr 17, 2016 at 5:24 - Yeah, definitely. Done. – StormShadow Commented Apr 17, 2016 at 7:24
- injected scripts can read what you want. you likely have timing issues. – Zig Mandel Commented Apr 17, 2016 at 13:59
-
What does
console.log(window)
log? – guest271314 Commented Apr 17, 2016 at 14:08 - It logs a window object that is missing the objects I'm looking for. I'd like to say it's timing issues, but the injected script runs on icon press, and I'm waiting for the page to fully load before pressing it. – StormShadow Commented Apr 17, 2016 at 23:26
3 Answers
Reset to default 6Soo, this is kind of hacky, but I was able to do it and it worked.
To gain access to everything available to the host window
, I had to create a script
element, put all the code I wanted in there, and add document.body.appendChild(script)
for it to work.
Not the sexiest way of doing things, but it will get the job done for small tasks.
Interesting question. Here is a quick and probably inplete answer :
- each tab has its own private separate
window
object background.js
also has its own- content scripts are a bit tricky in that while they nominally live inside the page, they actually keep a respectful distance : see isolated worlds
- I am not familiar with
chrome.tabs.executeScript
but somehow I would'nt trust it with anything beyond basics
One approach could be as follow :
Open the relevant page from the background script with chrome.tabs.create
: hence the backgound will have plete control and dominance over said tab and the window
, document
and your_object
therein. It will also be easier to handle the asynchronous side of thing : you'll learn to love callbacks.
Depending on what is required regarding the UX, another option would be to handle the async request, and fetch your_object
, entirely in background.js
One last hint : extensions you download from the store are just zipped files in your Chrome profile. Find tapermonkey.crx
or whatever, unzip it and read the sources to figure out what it does.
And oh, relying on timeout to handle asynchronicity is bound to random results.
According to documentation in https://developer.chrome./extensions/content_scripts
However, content scripts have some limitations. They cannot:
- Use variables or functions defined by web pages or by other content scripts.
So you can access the mon window variables from the content script, but not the variables created from the webpage's javascript, another content script or, as in your case, an object you have sent to the website.