Chrome扩展程序 - 从网页检索全局变量

时间:2021-04-25 23:37:58

I am working on an extension for Chrome. I wish parse the content of the "original" Gmail message (the currently viewed message).

我正在开发Chrome扩展程序。我希望解析“原始”Gmail邮件(当前查看的邮件)的内容。

I tried to utilize the jQuery.load() as follows

我试图利用jQuery.load()如下

$(windows).load(function() { alert(GLOBALS); });

and place it at the content script, but it does not work either. I am using Chrome's developer tools, which returns the following error on the invocation of the alert(GLOBALS);

并将其放在内容脚本中,但它也不起作用。我正在使用Chrome的开发人员工具,它会在调用警报时返回以下错误(GLOBALS);

Uncaught ReferenceError: GLOBALS is not defined

未捕获的ReferenceError:未定义GLOBALS

Although, when using the developers tools' console, typing into the console GLOBALS it returns an array.

虽然,当使用开发人员工具的控制台时,键入控制台GLOBALS它会返回一个数组。

Any clue how to access the GLOBALS from the content script?

有关如何从内容脚本访问GLOBALS的任何线索?

4 个解决方案

#1


70  

Content scripts run in an isolated environment. To get access to the any global properties (of the page's window), you have to either inject a new <script> element, or use event listeners for passing data.

内容脚本在隔离的环境中运行。要访问(页面窗口的)任何全局属性,您必须注入新的

See this answer for example on injecting a <script> element in the context of the page.

有关在页面上下文中注入

Example

contentscript.js ("run_at": "document_end" in manifest):

contentscript.js(清单中的“run_at”:“document_end”):

var s = document.createElement('script');
s.src = chrome.extension.getURL('script.js');
(document.head||document.documentElement).appendChild(s);
s.onload = function() {
    s.remove();
};

// Event listener
document.addEventListener('RW759_connectExtension', function(e) {
    // e.detail contains the transferred data (can be anything, ranging
    // from JavaScript objects to strings).
    // Do something, for example:
    alert(e.detail);
});

script.js - Located in the extension directory, this will be injected into the page itself:

script.js - 位于扩展目录中,它将被注入页面本身:

setTimeout(function() {
    /* Example: Send data from the page to your Chrome extension */
    document.dispatchEvent(new CustomEvent('RW759_connectExtension', {
        detail: GLOBALS // Some variable from Gmail.
    }));
}, 0);

Since this file is being loaded via a chrome-extension: URL from within the DOM, "script.js" must be added to the web_accessible_resources section of the manifest file. Otherwise Chrome will refuse to load the script file.

由于此文件是通过DOM中的chrome-extension:URL加载的,因此必须将“script.js”添加到清单文件的web_accessible_resources部分。否则Chrome将拒绝加载脚本文件。

You should run as little logic as possible in the web page, and handle most of your logic in the content script. This has multiple reasons. First and foremost, any script injected in the page runs in the same context as the web page, so the web page can (deliberately or inadvertently) modify JavaScript/DOM methods in such a way that your extension stops working. Secondly, content script have access to extra features, such a limited subset of the chrome.* APIs and cross-origin network requests (provided that the extension has declared permissions for those).

您应该在网页中尽可能少地运行逻辑,并在内容脚本中处理大部分逻辑。这有多种原因。首先,页面中注入的任何脚本都在与网页相同的上下文中运行,因此网页可以(故意或无意)修改JavaScript / DOM方法,使扩展程序停止工作。其次,内容脚本可以访问额外的功能,例如chrome。* API和跨源网络请求的有限子集(前提是扩展已声明这些功能的权限)。

#2


17  

A more modern solution for communicating between a chrome extension content_script and the javascript on the page would be to use the html5 postMessage API. Any messages sent to "window" are visible from both the javascript on the webpage and the extension's content_script.

用于在chrome扩展content_script和页面上的javascript之间进行通信的更现代的解决方案是使用html5 postMessage API。发送到“窗口”的任何消息都可以从网页上的javascript和扩展名的content_script中看到。

The extension's content_script.js:

扩展名的content_script.js:

window.addEventListener('message', function(event) {
    console.log('content_script.js got message:', event);
    // check event.type and event.data
});

setTimeout(function () {
    console.log('cs sending message');
    window.postMessage({ type: 'content_script_type',
                         text: 'Hello from content_script.js!'},
                       '*' /* targetOrigin: any */ );
}, 1000);

The javascript running on the webpage:

网页上运行的javascript:

window.addEventListener('message', function(event) {
    console.log('page javascript got message:', event);
});

setTimeout(function() {
    console.log('page javascript sending message');
    window.postMessage({ type: 'page_js_type',
                         text: "Hello from the page's javascript!"},
                       '*' /* targetOrigin: any */);
}, 2000);

Also see http://developer.chrome.com/extensions/content_scripts.html#host-page-communication

另请参阅http://developer.chrome.com/extensions/content_scripts.html#host-page-communication

#3


3  

There is a new API for web pages to communicate securely and without any side effects (window.postMessage can have other listeners!) to the content script.

有一个新的网页API可以安全地进行通信,而且没有任何副作用(window.postMessage可以有其他监听器!)到内容脚本。

"From the web page, use the runtime.sendMessage or runtime.connect APIs to send a message to a specific app or extension"

“从网页中,使用runtime.sendMessage或runtime.connect API将消息发送到特定应用或扩展”

// The ID of the extension we want to talk to.
var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";

// Make a simple request:
chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url},
  function(response) {
    if (!response.success)
    handleError(url);
});

"From your app or extension, you may listen to messages from web pages via the runtime.onMessageExternal or runtime.onConnectExternal APIs, similar to cross-extension messaging. Only the web page can initiate a connection. [...]"

“从您的应用程序或扩展程序中,您可以通过runtime.onMessageExternal或runtime.onConnectExternal API收听来自网页的消息,类似于跨扩展消息传递。只有网页才能启动连接。[...]”

(from http://developer.chrome.com/extensions/messaging.html) This is still only available in chrome's dev channel, but seems like it'll be in the next version or so.

(来自http://developer.chrome.com/extensions/messaging.html)这仍然只在chrome的开发频道中可用,但似乎它将在下一个版本左右。

Don't ask me how this works, it seems highly confusing. How on earth does chrome.runtime get defined on the web page? What if the script already defined that variable for some reason? I also couldn't find the chromium bug report to see the history of the development of this feature.

不要问我这是如何工作的,这似乎非常令人困惑。如何在网页上定义chrome.runtime?如果脚本由于某种原因已经定义了该变量怎么办?我也找不到铬虫报告,看看这个功能的发展历史。

#4


0  

I had a slightly different approach based on your extension's accessible html pages.

根据您的扩​​展程序的可访问html页面,我有一个稍微不同的方法。

Add your page to the manifest:

将您的页面添加到清单:

"web_accessible_resources": ["variables.html"]

Create your page (here, variables.html) and extract the content's data (i.e. window.contentVar):

创建您的页面(此处为variables.html)并提取内容的数据(即window.contentVar):

<script type="text/javascript">
  $("#my-var-name").text(window["contentVar"]);
</script>
<div id="my-var-name" style="display: none;"></div>

Access from your extension's JavaScript:

从您的扩展程序的JavaScript访问:

var myVarName = $("#my-var-name").text();

#1


70  

Content scripts run in an isolated environment. To get access to the any global properties (of the page's window), you have to either inject a new <script> element, or use event listeners for passing data.

内容脚本在隔离的环境中运行。要访问(页面窗口的)任何全局属性,您必须注入新的

See this answer for example on injecting a <script> element in the context of the page.

有关在页面上下文中注入

Example

contentscript.js ("run_at": "document_end" in manifest):

contentscript.js(清单中的“run_at”:“document_end”):

var s = document.createElement('script');
s.src = chrome.extension.getURL('script.js');
(document.head||document.documentElement).appendChild(s);
s.onload = function() {
    s.remove();
};

// Event listener
document.addEventListener('RW759_connectExtension', function(e) {
    // e.detail contains the transferred data (can be anything, ranging
    // from JavaScript objects to strings).
    // Do something, for example:
    alert(e.detail);
});

script.js - Located in the extension directory, this will be injected into the page itself:

script.js - 位于扩展目录中,它将被注入页面本身:

setTimeout(function() {
    /* Example: Send data from the page to your Chrome extension */
    document.dispatchEvent(new CustomEvent('RW759_connectExtension', {
        detail: GLOBALS // Some variable from Gmail.
    }));
}, 0);

Since this file is being loaded via a chrome-extension: URL from within the DOM, "script.js" must be added to the web_accessible_resources section of the manifest file. Otherwise Chrome will refuse to load the script file.

由于此文件是通过DOM中的chrome-extension:URL加载的,因此必须将“script.js”添加到清单文件的web_accessible_resources部分。否则Chrome将拒绝加载脚本文件。

You should run as little logic as possible in the web page, and handle most of your logic in the content script. This has multiple reasons. First and foremost, any script injected in the page runs in the same context as the web page, so the web page can (deliberately or inadvertently) modify JavaScript/DOM methods in such a way that your extension stops working. Secondly, content script have access to extra features, such a limited subset of the chrome.* APIs and cross-origin network requests (provided that the extension has declared permissions for those).

您应该在网页中尽可能少地运行逻辑,并在内容脚本中处理大部分逻辑。这有多种原因。首先,页面中注入的任何脚本都在与网页相同的上下文中运行,因此网页可以(故意或无意)修改JavaScript / DOM方法,使扩展程序停止工作。其次,内容脚本可以访问额外的功能,例如chrome。* API和跨源网络请求的有限子集(前提是扩展已声明这些功能的权限)。

#2


17  

A more modern solution for communicating between a chrome extension content_script and the javascript on the page would be to use the html5 postMessage API. Any messages sent to "window" are visible from both the javascript on the webpage and the extension's content_script.

用于在chrome扩展content_script和页面上的javascript之间进行通信的更现代的解决方案是使用html5 postMessage API。发送到“窗口”的任何消息都可以从网页上的javascript和扩展名的content_script中看到。

The extension's content_script.js:

扩展名的content_script.js:

window.addEventListener('message', function(event) {
    console.log('content_script.js got message:', event);
    // check event.type and event.data
});

setTimeout(function () {
    console.log('cs sending message');
    window.postMessage({ type: 'content_script_type',
                         text: 'Hello from content_script.js!'},
                       '*' /* targetOrigin: any */ );
}, 1000);

The javascript running on the webpage:

网页上运行的javascript:

window.addEventListener('message', function(event) {
    console.log('page javascript got message:', event);
});

setTimeout(function() {
    console.log('page javascript sending message');
    window.postMessage({ type: 'page_js_type',
                         text: "Hello from the page's javascript!"},
                       '*' /* targetOrigin: any */);
}, 2000);

Also see http://developer.chrome.com/extensions/content_scripts.html#host-page-communication

另请参阅http://developer.chrome.com/extensions/content_scripts.html#host-page-communication

#3


3  

There is a new API for web pages to communicate securely and without any side effects (window.postMessage can have other listeners!) to the content script.

有一个新的网页API可以安全地进行通信,而且没有任何副作用(window.postMessage可以有其他监听器!)到内容脚本。

"From the web page, use the runtime.sendMessage or runtime.connect APIs to send a message to a specific app or extension"

“从网页中,使用runtime.sendMessage或runtime.connect API将消息发送到特定应用或扩展”

// The ID of the extension we want to talk to.
var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";

// Make a simple request:
chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url},
  function(response) {
    if (!response.success)
    handleError(url);
});

"From your app or extension, you may listen to messages from web pages via the runtime.onMessageExternal or runtime.onConnectExternal APIs, similar to cross-extension messaging. Only the web page can initiate a connection. [...]"

“从您的应用程序或扩展程序中,您可以通过runtime.onMessageExternal或runtime.onConnectExternal API收听来自网页的消息,类似于跨扩展消息传递。只有网页才能启动连接。[...]”

(from http://developer.chrome.com/extensions/messaging.html) This is still only available in chrome's dev channel, but seems like it'll be in the next version or so.

(来自http://developer.chrome.com/extensions/messaging.html)这仍然只在chrome的开发频道中可用,但似乎它将在下一个版本左右。

Don't ask me how this works, it seems highly confusing. How on earth does chrome.runtime get defined on the web page? What if the script already defined that variable for some reason? I also couldn't find the chromium bug report to see the history of the development of this feature.

不要问我这是如何工作的,这似乎非常令人困惑。如何在网页上定义chrome.runtime?如果脚本由于某种原因已经定义了该变量怎么办?我也找不到铬虫报告,看看这个功能的发展历史。

#4


0  

I had a slightly different approach based on your extension's accessible html pages.

根据您的扩​​展程序的可访问html页面,我有一个稍微不同的方法。

Add your page to the manifest:

将您的页面添加到清单:

"web_accessible_resources": ["variables.html"]

Create your page (here, variables.html) and extract the content's data (i.e. window.contentVar):

创建您的页面(此处为variables.html)并提取内容的数据(即window.contentVar):

<script type="text/javascript">
  $("#my-var-name").text(window["contentVar"]);
</script>
<div id="my-var-name" style="display: none;"></div>

Access from your extension's JavaScript:

从您的扩展程序的JavaScript访问:

var myVarName = $("#my-var-name").text();