谷歌浏览器 - 使用iframe时屏幕截图失败,相同的脚本无需iframe

时间:2014-10-17 11:48:03

标签: javascript google-chrome iframe google-chrome-extension webrtc

当我使用以下脚本时,它适用于普通浏览器。但是当使用iframe时它会向我显示这个错误:

有谁知道造成这种情况的原因并且可以解决?

ERROR:

channel message Object {type: "getScreenPending", id: 24504, request: 6} content.js:4
channel message Object {type: "gotScreen", id: 24504, request: 6} content.js:4
>>> ShareScreen: if any err NavigatorUserMediaError {constraintName: "", message: "", name: "InvalidStateError"} test.js:1616

的manifest.json:

{
  "name": "Screen sharing",
  "description": "Screensharing utility",
  "version": "0.0.2",
  "manifest_version": 2,
  "minimum_chrome_version": "34",
  "icons": {
    "48" : "icon.png"
  },
  "permissions": [
    "desktopCapture"
  ],
  "background": {
    "scripts": ["background.js"]
  },
  "content_scripts": [ {
    "js": [ "content.js" ],
    "all_frames": true,
    "run_at": "document_start",
    "matches": ["*://*.a.com/*", "*://*.b.com/*"]
  }],
  "web_accessible_resources": [
        "icon.png"
  ]
}

background.js:

/* background page, responsible for actually choosing media */
chrome.runtime.onConnect.addListener(function (channel) {
    channel.onMessage.addListener(function (message) {
        switch(message.type) {
        case 'getScreen':
            var pending = chrome.desktopCapture.chooseDesktopMedia(message.options || ['screen', 'window'], 
                                                                   channel.sender.tab, function (streamid) {
                // communicate this string to the app so it can call getUserMedia with it
                message.type = 'gotScreen';
                message.sourceId = streamid;
                channel.postMessage(message);
            });
            // let the app know that it can cancel the timeout
            message.type = 'getScreenPending';
            message.request = pending;
            channel.postMessage(message);
            break;
        case 'cancelGetScreen':
            chrome.desktopCapture.cancelChooseDesktopMedia(message.request);
            message.type = 'canceledGetScreen';
            channel.postMessage(message);
            break;
        }
    });
});

content.js:

/* the chrome content script which can listen to the page dom events */
var channel = chrome.runtime.connect();
channel.onMessage.addListener(function (message) {
    console.log('channel message', message);
    window.postMessage(message, '*');
});

window.addEventListener('message', function (event) {
    if (event.source != window)
        return;
    if (!event.data && (event.data.type == 'getScreen' || event.data.type == 'cancelGetScreen'))
        return;
    channel.postMessage(event.data);
});

2 个答案:

答案 0 :(得分:6)

这是因为一个流只能由其URL匹配选项卡原点的帧使用。从Chrome 40开始,如果您将tab.url设置为原点与框架(crbug.com/425344)匹配的网址,您也可以在框架中使用流。

该流仅在十秒内有效,因此您必须遵循以下流程:

  1. 加载包含应处理流的页面的iframe。此页必须来自安全方案,例如https:chrome-extension:
  2. 将框架的原点(location.origin)发送到背景页面。
  3. 使用标签信息请求桌面流,tab.url设置为框架的网址或来源。
  4. 将streamId发送回框架并使用它(在十秒内)。
  5. 示例(基于问题中的代码):

    var tab = channel.sender.tab;
    // NEW (Chrome 40+)
    tab.url = message.url; // Your custom message, e.g. {url: location.origin}
    chrome.desktopCapture.chooseDesktopMedia(['screen', 'window'], tab,
        function (streamid) {
            // ... see question for the rest of the code
        });
    

答案 1 :(得分:0)

1 - 这不是代码问题,浏览器问题

2 - 这不起作用,因为我正在使用iframe启动HTTP(http://www.maindomain.com)扩展程序使用浏览器扩展程序的HTTPS(https://subdomain.maindomain.com)链接

所以要解决它。我需要使用HTTPS(https://www.maindomain.com)打开HTTPS iframe链接(https://subdomain.maindomain.com)。从那以后它现在起作用了。

希望这有助于他人。

注意:出现问题:当我从相同的子域subdomain.maindomain.com/test.php(iframe src = subdomain.maindomain.com / core.php)运行iframe时,它可以正常工作。但是,当我将其作为maindomain.com/otherpages(iframe src = subdomain.maindomain.com / core.php)运行时,这不起作用。非常混乱。

编辑:这仍然没有解决问题。屏幕共享对话框打开,但是当我按下共享屏幕时,它会出现相同的错误并失败。