内容脚本看到错误的Document元素

时间:2015-01-27 09:02:41

标签: javascript dom google-chrome-extension

我目前正在开发Chrome扩展程序,试图从当前标签页中显示的页面中获取突出显示的文字。

它适用于一些简单的页面,例如维基百科,但不适用于某些复杂的页面,尤其是http://www.nytimes.com/等主要媒体页面。

当我在下面调试我的内容脚本时,似乎文档或窗口元素与我的Chrome标签页中显示的页面不对应。

这是我的manifest.json:

{
  "name": "Capitalize!t2",
  "version": "3.1.2",
  "manifest_version": 2,
  "minimum_chrome_version": "29",
  "browser_action": {
    "default_icon": "icon-small.png",
    "default_popup": "popup.html"
  },
  "content_scripts": [ {
    "js": [ "selectionjfm.js","jquery-1.11.1.min.js","jquery-ui.min.js" ],
    "css":["jquery-ui.css"],
    "matches": [ "http://*/*", "https://*/*"],
    "all_frames":true
    }],
   "icons"  : { "16": "icon-small.png",
           "48": "icon.png",
          "128": "icon-small.png" },
  "key": "MXXXXXX",
  "permissions": [
    "https://secure.flickr.com/","identity", "https://accounts.google.com/*", "https://www.googleapis.com/*","https://spreadsheets.google.com/*","tabs","storage","<all_urls>"
  ],
  "oauth2": {
    "client_id": "XXXXXX",
    "scopes": ["https://www.googleapis.com/auth/plus.login","https://spreadsheets.google.com/feeds"]
  }
}

这是我的popup.js的有趣部分

function extractselection(id)
{
chrome.tabs.query({active:true, windowId: chrome.windows.WINDOW_ID_CURRENT}, 
  function(tab) {
    chrome.tabs.sendMessage(tab[0].id, {method: "getSelection"}, 
    function(response){
      var text = document.getElementById(id); 
      if(response!=null){
      text.innerHTML = response.data;
      }
    });
  });
  }

这是我的内容脚本(selectionjfm.cs),有点乱,我很抱歉。

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
  //console.log("grrroooooooove"+request.method);
  var toto="";
  if (request.method == "getSelection"){
    var frame= document.getElementsByTagName('iframe');
    if(frame!=null && frame.length>0){
        for(var i=0;i<frame.length;i++){
            win= frame[i].contentWindow;
            idoc=win.document;
            if(idoc.getSelection){
                toto+=idoc.getSelection().toString();
            }
        }
        //else console.log("no selection");
    }

    //console.log('totototo:'+window.getSelection().toString());

    toto+=window.getSelection().toString();
    toto+=document.getSelection().toString();
    var html = document.getElementsByTagName('html')[0].innerHTML;
    sendResponse({data: toto });
    }
  else{
   //console.log('nullll');
    sendResponse({}); // snub them.

    }
});

如果我转到a NY Times page,运行我的应用程序并查看调试控制台,我可以看到我的文档元素URI实际上是:

`googleads.g.doubleclick.net/pagead/ads?...`

我可以在document.referer中看到好的网址。

我想知道是否有人可以解释重定向以及是否有办法避免它......

3 个答案:

答案 0 :(得分:1)

您正在匹配每个网址,明确文档中的每一帧。

在您打开的文档中,有一个包含该网址的广告框架。

当您使用chrome.tabs.sendMessage广播消息时,无法告诉API它应该转到哪个帧:该选项卡中的所有帧获取它,无论是正在侦听还是不

但是,由于Chrome中的消息传递性质,您只能第一次sendResponse()来电成功。基本上,你已经有了竞争条件。

请参阅最后的说明:Simple one-time requests

  

注意:如果有多个网页正在侦听onMessage个事件,则只有第一个为特定事件调用sendResponse()才能成功发送响应。对该事件的所有其他回复都将被忽略。

最简单的解决方案是从清单中删除"all_frames": true。如果确实需要它,您可以在内容脚本本身determine whether you are a top level frame(例如使用window.parent == window)并决定基于此回复sendResponse

答案 1 :(得分:0)

我不认为你被重定向。您发布的URI来自嵌入NYTimes文章的广告。您可能会发现chrome.windows.WINDOW_ID_CURRENT指的是该广告的框架而不是父窗口。

考虑在debugger回调中的第一行使用chrome.extension.onMessage语句(或setting a breakpoint),然后单步执行代码以查看哪些内容出错。

答案 2 :(得分:0)

感谢Xan我找到了一种解决方案:

在我的程序中,我知道我想从中获取选择的页面/帧的URL是什么。

所以我正在做的是我从popup.js发送消息以及我想要捕获的页面/帧的URI。

function extractselection(id,**urllink**)
{
chrome.tabs.query({active:true, windowId: chrome.windows.WINDOW_ID_CURRENT}, 
  function(tab) {
    chrome.tabs.sendMessage(tab[0].id, {method: "getSelection",**urllink:urllink**}, 
    function(response){
      var text = document.getElementById(id); 
      if(response!=null){
      text.innerHTML = response.data;
      }
    });
  });
  }

在我的内容脚本中,我检查框架网址,如果它与我要查找的网址相匹配,我发送的是响应,否则不会

内容脚本:

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
  //console.log("grrroooooooove"+request.method);
  var toto="";
  if (request.method == "getSelection" && document.URL==request.urllink){
    var frame= document.getElementsByTagName('iframe');
    if(frame!=null && frame.length>0){
        for(var i=0;i<frame.length;i++){
            win= frame[i].contentWindow;
            idoc=win.document;
            if(idoc.getSelection){
                toto+=idoc.getSelection().toString();
            }
        }
        //else console.log("no selection");
    }

    //console.log('totototo:'+window.getSelection().toString());

    toto+=window.getSelection().toString();
    toto+=document.getSelection().toString();
    var html = document.getElementsByTagName('html')[0].innerHTML;
    sendResponse({data: toto });
    }
 // else{
   //console.log('nullll');
 //   sendResponse({}); // snub them.

    //}
});

清单保持不变。