5

내 콘텐츠 스크립트에서 내 popup.html에 응답이 표시되지 않습니다. 이 코드가 실행되고 찾기 버튼을 클릭하면 "Hello from response!" 인쇄되지만 변수 응답은 정의되지 않은 것으로 인쇄됩니다. 궁극적 인 목표는 현재 탭의 DOM을 스크립트 파일로 가져와 구문 분석 할 수 있도록하는 것입니다. DOM을 얻기 위해 콘텐츠 스크립트에 단일 메시지를 사용하고 있지만 반환되지 않고 정의되지 않은 것으로 표시됩니다. 가능한 모든 도움을 찾고 있습니다. 감사.크롬 확장 프로그램에서 콘텐츠 스크립트의 정의되지 않은 응답

popup.html :

<!DOCTYPE html> 
<html> 
    <body> 
     <head> 
     <script src="script.js"></script> 
     </head> 

     <form > 
      Find: <input id="find" type="text"> </input> 
     </form> 
     <button id="find_button"> Find </button> 
    </body> 
</html> 

의 manifest.json :

{ 
    "name": "Enhanced Find", 
    "version": "1.0", 
    "manifest_version": 2, 
    "description": "Ctrl+F, but better", 
    "browser_action": { 
     "default_icon": "icon.png", 
     "default_popup": "popup.html" 
    }, 
    "permissions": [ 
     "tabs", 
     "*://*/*" 
    ], 

    "background":{ 
     "scripts": ["script.js"], 
     "persistent": true 
    }, 

    "content_scripts":[ 
     { 
      "matches": ["http://*/*", "https://*/*"], 
      "js": ["content_script.js"], 
      "run_at": "document_end" 
     } 
    ] 
} 

script.js :

var bkg = chrome.extension.getBackgroundPage(); 


function eventHandler(){ 
    var input = document.getElementById("find"); 
    var text = input.value; 
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs){ 
     var tab = tabs[0]; 
     var url = tab.url; 
     chrome.tabs.sendMessage(tab.id, {method: "getDocuments"}, function(response){ 
      bkg.console.log("Hello from response!"); 
      bkg.console.log(response); 
     }); 

    }); 
} 

content_script.js :

var bkg = chrome.extension.getBackgroundPage(); 

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){ 
    if(request.method == "getDOM"){ 
     sendResponse({data : bkg.document}); 
    }else{ 
     sendResponse({}); 
    } 
}); 
+0

몇 가지 발언 : 1. 당신은 메시지를 보내는'{ method : "getDocuments"}', 그러나'{method : "getDOM"}'을 들어라. 2. 메시지가 일치하더라도 배경 페이지의 문서를 다시 보냅니다. 3. 두 개의 인스턴스 인'script.js'를 실행하고 있습니다 : 하나는 백그라운드 페이지에, 다른 하나는 팝업에 있습니다. 4. 배경 페이지, 팝업, 내용 스크립트와 같은 용어를 직접 입력해야합니다. 5. 이벤트 페이지 (비 지속적인 배경 페이지)가 똑같이 효과적이지만 훨씬 "자원 친화적"인 경우 영구적 인 배경 페이지를 사용하고 있습니다. – gkalpak

+0

(그렇습니다. 곧 답변을 드리겠습니다.) – gkalpak

+0

아래에서 제안한 솔루션을 사용해 보셨습니까? 너에게 효과가 있었 니? – gkalpak

답변

15

코드에 많은 문제가 있습니다 (위의 내용 참조). 첫째


제안/고려 사항 :

  • 모든 웹 페이지에 콘텐츠 스크립트를 삽입하지 마십시오. Inject programmatically 및 사용자가 검색하려고 할 때만.

  • DOM에 직접 액세스하고 조작 할 수있는 콘텐츠 스크립트 (예 : 검색 결과 강조 표시)에서 "검색"권한을 수행하는 것이 좋습니다. 이 방법을 사용하려면 권한을 조정해야하지만 항상 최소로 유지하십시오 (예 : , activeTab 등으로 충분하지 않은 경우).

  • 팝업이 닫히거나 숨겨지면 (예 : 탭이 포커스를 받으면) 팝업 컨텍스트에서 실행중인 모든 JS가 중단된다는 점에 유의하십시오.

  • 일부 영속성 (일시적)을 원한다면. 최근 결과 또는 마지막 검색어를 기억하면 chrome.storage 또는 localStorage과 같은 것을 사용할 수 있습니다. 마지막으로


, 확장의 내 데모 버전에서 샘플 코드 :

확장 파일 조직 :

  extension-root-directory/ 
      | 
      |_____fg/ 
      |  |_____content.js 
      | 
      |_____popup/ 
      |  |_____popup.html 
      |  |_____popup.js 
      | 
      |_____manifest.json 

의 manifest.json :

{ 
    "manifest_version": 2, 
    "name": "Test Extension", 
    "version": "0.0", 
    "offline_enabled": true, 

    "content_scripts": [ 
     { 
      "matches": [ 
       "http://*/*", 
       "https://*/*" 
      ], 
      "js":  ["fg/content.js"], 
      "run_at": "document_end", 
     } 
    ], 

    "browser_action": { 
     "default_title": "Test Extension", 
     "default_popup": "popup/popup.html" 
    } 
} 

콘텐츠.JS :

// Listen for message... 
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { 
    // If the request asks for the DOM content... 
    if (request.method && (request.method === "getDOM")) { 
     // ...send back the content of the <html> element 
     // (Note: You can't send back the current '#document', 
     // because it is recognised as a circular object and 
     // cannot be converted to a JSON string.) 
     var html = document.all[0]; 
     sendResponse({ "htmlContent": html.innerHTML }); 
    } 
}); 

popup.html :

<!DOCTYPE html> 
<html> 
    <head> 
     <script type="text/javascript" src="popup.js"></script> 
    </head> 
    <body> 
     Search: 
     <input type="text" id="search" /> 
     <input type="button" id="searchBtn" value=" Find " 
       style="width:100%;" /> 
    </body> 
</html> 

popup.js : 스타터

window.addEventListener("DOMContentLoaded", function() { 
    var inp = document.getElementById("search"); 
    var btn = document.getElementById("searchBtn"); 

    btn.addEventListener("click", function() { 
     var searchTerm = inp.value; 
     if (!inp.value) { 
      alert("Please, enter a term to search for !"); 
     } else { 
      // Get the active tab 
      chrome.tabs.query({ 
       active: true, 
       currentWindow: true 
      }, function(tabs) { 
       // If there is an active tab... 
       if (tabs.length > 0) { 
        // ...send a message requesting the DOM... 
        chrome.tabs.sendMessage(tabs[0].id, { 
         method: "getDOM" 
        }, function(response) { 
         if (chrome.runtime.lastError) { 
          // An error occurred :(
          console.log("ERROR: ", chrome.runtime.lastError); 
         } else { 
          // Do something useful with the HTML content 
          console.log([ 
           "<html>", 
           response.htmlContent, 
           "</html>" 
          ].join("\n")); 
         } 
        }); 
       } 
      }); 
     } 
    }); 
}); 
+0

이 응답에 너무 많은 좋은 정보가 있습니다. 나는 두 번 upvote 할 수 있었으면 좋겠습니다. 훌륭한 리소스는 올바르게 설계된 확장 프레임 워크를 구축 할 extensionizr.com입니다. – TrophyGeek

+0

이봐, downvote 무엇입니까 ??? – gkalpak

+0

음 ... 나? 나는 upvoted. – TrophyGeek