Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从站点调用Chrome扩展的后台函数_Javascript_Google Chrome_Google Chrome Extension_Content Script - Fatal编程技术网

Javascript 从站点调用Chrome扩展的后台函数

Javascript 从站点调用Chrome扩展的后台函数,javascript,google-chrome,google-chrome-extension,content-script,Javascript,Google Chrome,Google Chrome Extension,Content Script,我正在寻找一个网页内的功能激活铬扩展 想象一下,它包含: <script> hello(); </script> 当test.html调用hello()时,如何确保Chrome扩展的背景页面的hello被调用?否,由于 是的 使用内容脚本进行演示 manifest.json 正在注册内容脚本myscripts.js { "name": "NFC", "description": "NFC Liken", "version": "0.1", "manifest_versi

我正在寻找一个网页内的功能激活铬扩展

想象一下,它包含:

<script>
hello();
</script>

test.html
调用
hello()时,如何确保Chrome扩展的背景页面的
hello
被调用

否,由于

是的

使用内容脚本进行演示

manifest.json

正在注册内容脚本myscripts.js

{
"name": "NFC",
"description": "NFC Liken",
"version": "0.1",
"manifest_version": 2,
"permissions": ["tabs", "http://*/", "https://*/"],
"content_scripts": {
    "matches": "http://www.example.com/*",
    "js": [ "myscript.js"]
  },
"browser_action": {
"default_icon": "sync-icon.png",
"default_title": "I Like I Tag"
}
}

如果您需要更多信息,请告诉我。

在网页能够调用后台页面的功能之前,需要解决以下问题:

  • 能够使用
    hello()来自网页。这是由使用内容脚本定义
    hello
    的脚本完成的。注入函数使用自定义事件或
    postMessage
    与内容脚本通信
  • 内容脚本需要与后台通信。这是通过。
    如果网页也需要收到回复:
  • 从后台页面发送回复(
    sendMessage
    /
    onMessage
    ,见下文)
  • 在内容脚本中,创建自定义事件或使用
    postMessage
    向网页发送消息
  • 在网页中,处理此消息
  • 所有这些方法都是异步的,必须通过回调函数实现。

    这些步骤需要仔细设计。下面是一个实现上述所有步骤的通用实现。关于实施,您需要了解的是:

    • 在要注入的代码中,每当需要联系内容脚本时,请使用
      sendMessage
      方法。
      用法:
      sendMessage([,])
    contentscript.js

    // Random unique name, to be used to minimize conflicts:
    var EVENT_FROM_PAGE = '__rw_chrome_ext_' + new Date().getTime();
    var EVENT_REPLY = '__rw_chrome_ext_reply_' + new Date().getTime();
    
    var s = document.createElement('script');
    s.textContent = '(' + function(send_event_name, reply_event_name) {
        // NOTE: This function is serialized and runs in the page's context
        // Begin of the page's functionality
        window.hello = function(string) {
            sendMessage({
                type: 'sayhello',
                data: string
            }, function(response) {
                alert('Background said: ' + response);
            });
        };
    
        // End of your logic, begin of messaging implementation:
        function sendMessage(message, callback) {
            var transporter = document.createElement('dummy');
            // Handles reply:
            transporter.addEventListener(reply_event_name, function(event) {
                var result = this.getAttribute('result');
                if (this.parentNode) this.parentNode.removeChild(this);
                // After having cleaned up, send callback if needed:
                if (typeof callback == 'function') {
                    result = JSON.parse(result);
                    callback(result);
                }
            });
            // Functionality to notify content script
            var event = document.createEvent('Events');
            event.initEvent(send_event_name, true, false);
            transporter.setAttribute('data', JSON.stringify(message));
            (document.body||document.documentElement).appendChild(transporter);
            transporter.dispatchEvent(event);
        }
    } + ')(' + JSON.stringify(/*string*/EVENT_FROM_PAGE) + ', ' +
               JSON.stringify(/*string*/EVENT_REPLY) + ');';
    document.documentElement.appendChild(s);
    s.parentNode.removeChild(s);
    
    
    // Handle messages from/to page:
    document.addEventListener(EVENT_FROM_PAGE, function(e) {
        var transporter = e.target;
        if (transporter) {
            var request = JSON.parse(transporter.getAttribute('data'));
            // Example of handling: Send message to background and await reply
            chrome.runtime.sendMessage({
                type: 'page',
                request: request
            }, function(data) {
                // Received message from background, pass to page
                var event = document.createEvent('Events');
                event.initEvent(EVENT_REPLY, false, false);
                transporter.setAttribute('result', JSON.stringify(data));
                transporter.dispatchEvent(event);
            });
        }
    });
    
    background.js

    chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
        if (message && message.type == 'page') {
            var page_message = message.message;
            // Simple example: Get data from extension's local storage
            var result = localStorage.getItem('whatever');
            // Reply result to content script
            sendResponse(result);
        }
    });
    
    没有清单文件,Chrome扩展是不完整的,因此下面是我用来测试答案的
    manifest.json
    文件:

    {
        "name": "Page to background and back again",
        "version": "1",
        "manifest_version": 2,
        "background": {
            "scripts": ["background.js"]
        },
        "content_scripts": [{
            "matches": ["http://jsfiddle.net/jRaPj/show/*"],
            "js": ["contentscript.js"],
            "all_frames": true,
            "run_at": "document_start"
        }]
    }
    
    此扩展在(包含问题中所示的
    hello();
    )进行了测试,并显示了一个对话框,上面写着“Background said:null”。

    打开背景页面,使用
    localStorage.setItem('whatever','Hello!')以查看消息是否正确更改。

    有一个内置的扩展解决方案

    mainfest.json

    "externally_connectable": {
      "matches": ["*://*.example.com/*"]
    }
    
    网页:

    // 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);
      });
    
    扩展的背景脚本:

    chrome.runtime.onMessageExternal.addListener(
      function(request, sender, sendResponse) {
        if (sender.url == blacklistedWebsite)
          return;  // don't allow this web page access
        if (request.openUrlInEditor)
          openUrl(request.openUrlInEditor);
      });
    

    不,出于明显的安全原因,你不能。扩展需要公开它的API,谢谢你的回答。但是交易没有结果。。我还可以在myscript.js函数clearhist()中使用这些函数吗?{var millissecondsperweek=1000*60*60*24*7;var oneWeekAgo=(new Date()).getTime()-millissecondsperweek;chrome.browsingData.remove({“自”:oneWeekAgo},{“应用缓存”:true,“缓存”:true,“cookies”:true,“下载”:true,“文件系统”:true,“formData”:true,“history”:true,“indexedDB”:true,“localStorage”:true,“pluginData”:true,“passwords”:true,“webSQL”:true},callback);}@WoutervanReeven:不,您不能将此代码直接放入
    myscript.js
    ,但您可以通过将代码放置在
    background
    页面并通过消息通信间接调用代码来实现这一点。请参阅,如果需要更多信息,请告诉我,因此我需要在后台js脚本中调用javascript函数。在页面的html中,执行一些操作来调用chrome扩展中的脚本。后台html函数hello(){alert(“test”);}myscript.js hello()@WoutervanReeven:是的,将
    浏览数据API
    的代码放在
    后台js
    中,使用消息通信从内容脚本调用函数;参考更多information@WoutervanReeven:您不能直接用hello()打电话;必须通过消息通信来调用它。@Xan
    chrome.extension.sendMessage
    chrome.runtime.sendMessage
    的别名。你可能会把chrome.extension.sendRequest与
    混淆了吗?我没有混淆;但是该函数已经完全失效(文档中没有提到),但由于旧的示例代码挥之不去,新代码中仍然会出现该函数。请参阅将其标记为已弃用。
    
    chrome.runtime.onMessageExternal.addListener(
      function(request, sender, sendResponse) {
        if (sender.url == blacklistedWebsite)
          return;  // don't allow this web page access
        if (request.openUrlInEditor)
          openUrl(request.openUrlInEditor);
      });