80

これは最も簡単な方法のようですが、機能していません。通常のブラウザでは、.htmlファイルと.jsファイルは完全に機能しますが、Chrome / Firefox拡張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も添付します。

マニフェスト.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/"
  ]
}
4

5 に答える 5

137

Chrome拡張機能では、インラインJavaScript(ドキュメント)を使用できません。
Firefox WebExtensions(ドキュメント)についても同じことが言えます。

あなたはこれに似た何かをしなければならないでしょう:

リンクに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');
    });
});

popup.js別のスクリプトファイルとしてロードする必要があります。

<script src="popup.js"></script>
于 2012-11-27T19:58:50.713 に答える
45

理由

Chromeは、コンテンツセキュリティポリシーを介して拡張機能のあらゆる種類のインラインコードを禁止しているため、これは機能しません。

インラインJavaScriptは実行されません。<script>この制限により、インラインブロックインラインイベントハンドラーの両方が禁止されます(例<button onclick="...">)。

検出する方法

これが実際に問題である場合、Chromeはコンソールに次のエラーを生成します。

次のコンテンツセキュリティポリシーディレクティブに違反しているため、インラインスクリプトの実行を拒否しました: "script-src'self' chrome-extension-resource:"。インライン実行を有効にするには、'unsafe-inline'キーワード、ハッシュ('sha256 -...')、またはナンス('nonce -...')のいずれかが必要です。

ポップアップのJavaScriptコンソール(一般的なデバッグに役立ちます)にアクセスするには、拡張機能のボタンを右クリックして、コンテキストメニューから[ポップアップの検査]を選択します。

ポップアップのデバッグの詳細については、こちらをご覧ください

直し方

すべてのインラインJavaScriptを削除する必要があります。Chromeのドキュメントにガイドがあります。

オリジナルが次のようになっているとします。

<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'ても効果はありません。

更新: Chrome 46以降、特定のインラインコードブロックをホワイトリストに登録することが可能です。

Chrome 46以降、ポリシーでソースコードのbase64でエンコードされたハッシュを指定することで、インラインスクリプトをホワイトリストに登録できます。このハッシュには、使用するハッシュアルゴリズム(sha256、sha384、またはsha512)をプレフィックスとして付ける必要があります。例については、要素のハッシュの使用法を<script>参照してください。

ただし、これを使用する理由はすぐにはわかりません。また、のようなインライン属性は有効になりませんonclick="code"

于 2014-09-08T09:46:57.630 に答える
1

同じ問題が発生し、コードを書き直したくなかったので、コードを変更してインラインで宣言されたイベントを作成する関数を作成しました。

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');
})

これにより、選択したノードからすべてのインラインイベントが削除され、代わりにjqueryを使用して再作成されます。

于 2015-08-04T21:39:15.643 に答える
1

私の場合に使用した例を公開することにしました。スクリプトを使用してdivのコンテンツを置き換えようとしました。私の問題は、Chromeがそのスクリプトを認識しない/実行しないことでした。

詳細私がやりたかったこと:リンクをクリックし、そのリンクをクリックして外部のhtmlファイルを「読み取る」には、divセクションにロードされます。

  • 呼び出されたIDを持つDIVの前にスクリプトを配置すると、スクリプトが機能しないことがわかりました。
  • スクリプトが別のDIVにある場合も、機能しません
  • スクリプトは、説明どおりにdocument.addEventListener('DOMContentLoaded'、function()を使用してコーディングする必要があります

        <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>
    
于 2018-10-31T19:46:10.197 に答える
1

すでに述べたように、Chrome拡張機能では、セキュリティ上の理由からインラインJavaScriptを使用できないため、この回避策も試すことができます。

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 class="clickableBtn">
                  hyhy
            </a>
        </body>
    </html>
<!doctype html>

popup.js

window.onclick = function(event) {
    var target = event.target ;
    if(target.matches('.clickableBtn')) {
        var clickedEle = document.activeElement.id ;
        var ele = document.getElementById(clickedEle);
        alert(ele.text);
    }
}

または、Jqueryファイルが含まれている場合は

window.onclick = function(event) {
    var target = event.target ;
    if(target.matches('.clickableBtn')) {
        alert($(target).text());
    }
}
于 2020-04-20T18:34:18.053 に答える