크롬 확장에서 현재 페이지의 소스 HTML 가져 오기


85

크롬 확장 프로그램이 있습니다. 현재 페이지의 HTML 소스에서 분석해야합니다. 여기에서 배경 페이지와 콘텐츠 스크립트가있는 모든 종류의 솔루션을 찾았지만 아무도 도움이되지 않았습니다. 여기 내가 지금까지 가지고있는 것 :
manifest.json :

{
  "name": "Extension",
  "version": "1.0",
  "description": "Extension",
  "browser_action": {
    "default_icon": "bmarkred.ico",
    "popup": "Test.html"
  },
  "content_scripts": [
    {
      "matches": ["http://*/*"],
      "js": ["content.js"]
    }
  ],
  "background": {
    "page": "backgroundPage.html"
  },
  "permissions": [
    "cookies",
    "tabs",
    "http://*/*", 
    "https://*/*"
  ]
}

background.html :

<html>
<head>
<script type="text/javascript">
    try {
        chrome.tabs.getSelected(null, function (tab) {
            chrome.tabs.sendRequest(tab.id, {action: "getSource"}, function(source) {
                alert(source);
            });
        });
    }
    catch (ex) {
        alert(ex);
    }
</script>
</head>
</html>

content.js :

chrome.extension.onRequest.addListener(function(request, sender, callback) {
    if (request.action == "getSource") {
        callback(document.getElementsByTagName('html')[0].innerHTML);
    }
});

경고는 항상 정의되지 않은 경고입니다. content.js 파일에서 콜백 함수를 다음과 같이 변경하더라도 :

callback('hello'); 

여전히 같은 결과입니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 아마도 나는 잘못된 길로 가고 있습니다. 내가 정말로 필요한 것은 이것입니다. 사용자가 확장 팝업을 열면 (그리고 그때만) 분석 할 수 있도록 현재 페이지의 HTML이 필요합니다. 어떤 제안?


문제는 백그라운드 페이지의 코드가 콘텐츠 스크립트가 삽입되기 전에 즉시 실행된다는 것입니다. 매우 유사하거나 중복 된 질문이 이전에 요청되었습니다. 새 Google 크롬 탭열고 소스 가져 오기 에서 답변을 확인 하세요 .
Rob W

답장 해 주셔서 감사합니다. 첨부 된 링크의 코드 세그먼트를 복사했지만 여전히 작동하지 않습니다. 문제는 내 확장이 팝업이고 사용자가 내 확장을 열 때만 HTML을 가져와야한다는 것입니다. 예를 들어 현재 탭이 facebook.com이면 확장 프로그램을 열 때만 html 소스를 내 js 파일 (콘텐츠 스크립트 나 배경 페이지가 아님)로 검색합니다.
Mr T.

현재 코드로 질문을 업데이트하십시오. 코드에는 문제를 강조하는 주석이 포함되어야합니다.
Rob W

답변:


155

소스를 가져올 페이지에 스크립트를 삽입하고 팝업에 다시 메시지를 보냅니다 ....

manifest.json

{
  "name": "Get pages source",
  "version": "1.0",
  "manifest_version": 2,
  "description": "Get pages source from a popup",
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "permissions": ["tabs", "<all_urls>"]
}

popup.html

<!DOCTYPE html>
<html style=''>
<head>
<script src='popup.js'></script>
</head>
<body style="width:400px;">
<div id='message'>Injecting Script....</div>
</body>
</html>

popup.js

chrome.runtime.onMessage.addListener(function(request, sender) {
  if (request.action == "getSource") {
    message.innerText = request.source;
  }
});

function onWindowLoad() {

  var message = document.querySelector('#message');

  chrome.tabs.executeScript(null, {
    file: "getPagesSource.js"
  }, function() {
    // If you try and inject into an extensions page or the webstore/NTP you'll get an error
    if (chrome.runtime.lastError) {
      message.innerText = 'There was an error injecting script : \n' + chrome.runtime.lastError.message;
    }
  });

}

window.onload = onWindowLoad;

getPagesSource.js

// @author Rob W <http://stackoverflow.com/users/938089/rob-w>
// Demo: var serialized_html = DOMtoString(document);

function DOMtoString(document_root) {
    var html = '',
        node = document_root.firstChild;
    while (node) {
        switch (node.nodeType) {
        case Node.ELEMENT_NODE:
            html += node.outerHTML;
            break;
        case Node.TEXT_NODE:
            html += node.nodeValue;
            break;
        case Node.CDATA_SECTION_NODE:
            html += '<![CDATA[' + node.nodeValue + ']]>';
            break;
        case Node.COMMENT_NODE:
            html += '<!--' + node.nodeValue + '-->';
            break;
        case Node.DOCUMENT_TYPE_NODE:
            // (X)HTML documents are identified by public identifiers
            html += "<!DOCTYPE " + node.name + (node.publicId ? ' PUBLIC "' + node.publicId + '"' : '') + (!node.publicId && node.systemId ? ' SYSTEM' : '') + (node.systemId ? ' "' + node.systemId + '"' : '') + '>\n';
            break;
        }
        node = node.nextSibling;
    }
    return html;
}

chrome.runtime.sendMessage({
    action: "getSource",
    source: DOMtoString(document)
});

@Gil Tankus 제 첫 게시물에 대해 죄송합니다. 댓글에 충분히주의를 기울이지 않았고 (다시) Rob W가 말한 내용을 역설하게되었습니다. 새 게시물에는 원하는 내용이 있어야합니다.
PAEz

감사합니다. 귀하의 답변은 정말 도움이되었습니다. 제 문제는 onMessage가 비동기 적으로 발생한다는 것입니다. 내 팝업에는 소스 HTML을 전달하는 모든 종류의 다른 항목이 있습니다. 소스를 전역 변수에 저장 한 다음 페이지 온로드 기능을 계속하려면 어떻게해야합니까?
Mr T.

나는 당신이 할 수 있다고 생각하지 않습니다. 당신은 그것을 콜백 코드 또는 함수에 넣고 콜백에서 호출해야 할 것입니다 ... JS만이 goto명령을 가지고 있다면 ? ; P
PAEz

19
DOMtoString 함수 대신 document.documentElement.outerHTML과 같은 것이 아닌 이유는 무엇입니까?
djfm

@djfm 그것은 거의 항상 괜찮을 것입니다. Rob W의 기능이 더 완벽하다고 말할 수있는 것입니다. 예를 들어 솔루션이 아닌 doctype을 반환합니다.
PAEz

0

내 해결책은 다음과 같습니다.

chrome.runtime.onMessage.addListener(function(request, sender) {
        if (request.action == "getSource") {
            this.pageSource = request.source;
            var title = this.pageSource.match(/<title[^>]*>([^<]+)<\/title>/)[1];
            alert(title)
        }
    });

    chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
        chrome.tabs.executeScript(
            tabs[0].id,
            { code: 'var s = document.documentElement.outerHTML; chrome.runtime.sendMessage({action: "getSource", source: s});' }
        );
    });
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.