programing

Chrome 확장 프로그램 내에서 onClick이 작동하지 않음

nasanasas 2020. 12. 3. 07:59
반응형

Chrome 확장 프로그램 내에서 onClick이 작동하지 않음


이것은 가장 쉬운 일인 것 같지만 작동하지 않습니다. 일반 브라우저에서는 .html 및 .js 파일이 완벽하게 작동하지만 Chrome 확장에서는 onClick기능이 수행해야하는 작업을 수행하지 않습니다.

.js 파일 :

function hellYeah(text) {
  document.getElementById("text-holder").innerHTML = text;
}

.html 파일 :

<!doctype html>
<html>
  <head>
    <title>
      Getting Started Extension's Popup
    </title>
    <script src="popup.js"></script>
  </head>
  <body>
    <div id="text-holder">
      ha
    </div>
    <br />
    <a onClick=hellYeah("xxx")>
      hyhy
    </a>
  </body>
</html>

따라서 기본적으로 사용자가 "hyhy"를 클릭하면 "ha"가 "xxx"로 변경됩니다. 그리고 다시 말하지만 브라우저에서는 완벽하게 작동하지만 확장 프로그램에서는 작동하지 않습니다. 그 이유를 아십니까? 아래 manifest.json도 첨부하는 경우를 대비하여.

미리 감사드립니다!

manifest.json :

{
  "name": "My First Extension",
  "version": "1.0",
  "manifest_version": 2,
  "description": "The first extension that I made.",
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "permissions": [
    "http://api.flickr.com/"
  ]
}

Chrome 확장 프로그램은 인라인 자바 스크립트를 허용하지 않습니다 ( 문서 ). 이와 비슷한 것을해야합니다.

링크에 ID를 할당하고 ( <a onClick=hellYeah("xxx")><a id="link">) addEventListener이벤트를 바인딩하는 데 사용 합니다. popup.js파일에 다음을 입력하십시오 .

document.addEventListener('DOMContentLoaded', function() {
    var link = document.getElementById('link');
    // onClick's logic below:
    link.addEventListener('click', function() {
        hellYeah('xxx');
    });
});

이유

Chrome 콘텐츠 보안 정책을 통해 확장 프로그램에서 모든 종류의 인라인 코드금지 하기 때문에 작동하지 않습니다 .

인라인 JavaScript는 실행되지 않습니다. 이 제한은 인라인 <script>블록 인라인 이벤트 핸들러 (예 :)를 모두 금지합니다 <button onclick="...">.

감지 방법

이것이 실제로 문제인 경우 Chrome은 콘솔에 다음 오류를 생성합니다.

다음 콘텐츠 보안 정책 지시문 'script-src'self 'chrome-extension-resource :'를 위반하여 인라인 스크립트 실행을 거부했습니다. 인라인 실행을 활성화하려면 'unsafe-inline'키워드, 해시 ( 'sha256 -...') 또는 nonce ( 'nonce -...')가 필요합니다.

팝업의 JavaScript 콘솔 (일반적으로 디버그에 유용함)에 액세스하려면 확장 버튼을 마우스 오른쪽 버튼으로 클릭하고 컨텍스트 메뉴에서 "팝업 검사"를 선택합니다.

팝업 디버깅에 대한 자세한 내용은 여기에서 확인할 수 있습니다 .

어떻게 고치는 지

모든 인라인 JavaScript를 제거해야합니다. 크롬 문서의 가이드 .

원본이 다음과 같다고 가정합니다.

<a onclick="handler()">Click this</a> <!-- Bad -->

onclick속성 을 제거 하고 요소에 고유 한 ID를 부여해야합니다.

<a id="click-this">Click this</a> <!-- Fixed -->

그런 다음 스크립트 ( .js파일에 있어야 함)에서 리스너를 첨부합니다 popup.js.

// Pure JS:
document.addEventListener('DOMContentLoaded', function() {
  document.getElementById("click-this").addEventListener("click", handler);
});

// The handler also must go in a .js file
function handler() {
  /* ... */
}

DOMContentLoaded이벤트 의 포장에 유의하십시오 . 이렇게하면 실행시 요소가 존재합니다. 이제 <head>문서의 예를 들어 스크립트 태그를 추가하십시오 .

<script src="popup.js"></script>

jQuery를 사용하는 경우 대안 :

// jQuery
$(document).ready(function() {
  $("#click-this").click(handler);
});

정책 완화

Q : 오류는 인라인 코드를 허용하는 방법을 언급합니다. 코드를 변경하고 싶지 않거나 변경할 수 없습니다. 인라인 스크립트를 활성화하려면 어떻게해야합니까?

A : 오류 내용에도 불구하고 인라인 스크립트를 활성화수 없습니다 .

인라인 JavaScript 실행에 대한 제한을 완화하는 메커니즘은 없습니다. 특히 포함하는 스크립트 정책을 설정해 'unsafe-inline'도 효과가 없습니다.

Update: Since Chrome 46, it's possible to whitelist specific inline code blocks:

As of Chrome 46, inline scripts can be whitelisted by specifying the base64-encoded hash of the source code in the policy. This hash must be prefixed by the used hash algorithm (sha256, sha384 or sha512). See Hash usage for <script> elements for an example.

However, I do not readily see a reason to use this, and it will not enable inline attributes like onclick="code".


I had the same problem, and didn´t want to rewrite the code, so I wrote a function to modify the code and create the inline declarated events:

function compile(qSel){
    var matches = [];
    var match = null;
    var c = 0;

    var html = $(qSel).html();
    var pattern = /(<(.*?)on([a-zA-Z]+)\s*=\s*('|")(.*)('|")(.*?))(>)/mg;

    while (match = pattern.exec(html)) {
        var arr = [];
        for (i in match) {
            if (!isNaN(i)) {
                arr.push(match[i]);
            }
        }
        matches.push(arr);
    }
    var items_with_events = [];
    var compiledHtml = html;

    for ( var i in matches ){
        var item_with_event = {
            custom_id : "my_app_identifier_"+i,
            code : matches[i][5],
            on : matches[i][3],
        };
        items_with_events.push(item_with_event);
        compiledHtml = compiledHtml.replace(/(<(.*?)on([a-zA-Z]+)\s*=\s*('|")(.*)('|")(.*?))(>)/m, "<$2 custom_id='"+item_with_event.custom_id+"' $7 $8");
    }

    $(qSel).html(compiledHtml);

    for ( var i in items_with_events ){
        $("[custom_id='"+items_with_events[i].custom_id+"']").bind(items_with_events[i].on, function(){
            eval(items_with_events[i].code);
        });
    }
}

$(document).ready(function(){
    compile('#content');
})

This should remove all inline events from the selected node, and recreate them with jquery instead.


I decide to publish my example that I used in my case. I tried to replace content in div using a script. My problem was that Chrome did not recognized / did not run that script.

In more detail What I wanted to do: To click on a link, and that link to "read" an external html file, that it will be loaded in a div section.

  • I found out that by placing the script before the DIV with ID that was called, the script did not work.
  • If the script was in another DIV, also it does not work
  • The script must be coded using document.addEventListener('DOMContentLoaded', function() as it was told

        <body>
        <a id=id_page href ="#loving"   onclick="load_services()"> loving   </a>
    
            <script>
                    // This script MUST BE under the "ID" that is calling
                    // Do not transfer it to a differ DIV than the caller "ID"
                    document.getElementById("id_page").addEventListener("click", function(){
                    document.getElementById("mainbody").innerHTML = '<object data="Services.html" class="loving_css_edit"; ></object>'; });
                </script>
        </body>
    
      <div id="mainbody" class="main_body">
            "here is loaded the external html file when the loving link will 
             be  clicked. "
      </div>
    

참고URL : https://stackoverflow.com/questions/13591983/onclick-within-chrome-extension-not-working

반응형