OnClick或Inline脚本不在扩展中工作

发布于 2025-01-26 09:03:51 字数 1184 浏览 3 评论 0原文

这似乎是最简单的事情,但这只是不起作用。在普通浏览器中,.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”。再说一次 - 它在浏览器中完美工作,但在扩展方面不起作用。你知道为什么吗?以防万一我还附加了清单。

清单: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/"
  ]
}

This seems to be the easiest thing to do, but it's just not working. In a normal browser the .html and .js files works perfectly, but in the Chrome/Firefox extension the onClick function is not performing what it's supposed to do.

.js file:

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

.html file:

<!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>

So basically once the user clicks "hyhy", "ha" should change into "xxx". And again - it works perfectly in the browser but does not work in the extension. Do you know why? Just in case I'm attaching the manifest.json below as well.

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/"
  ]
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

○闲身 2025-02-02 09:03:51

Chrome Extensions不允许您具有内联JavaScript(
Firefox Webextensions(
)。

您将必须做类似的事情:

将ID分配给链接(&lt; a onClick = hellyeah(“ xxx”)&gt; sust &lt; a ID =“ link “&gt;),并使用 绑定事件。将以下内容放入您的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>

Chrome Extensions don't allow you to have inline JavaScript (documentation).
The same goes for Firefox WebExtensions (documentation).

You are going to have to do something similar to this:

Assign an ID to the link (<a onClick=hellYeah("xxx")> becomes <a id="link">), and use addEventListener to bind the event. Put the following in your popup.js file:

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

popup.js should be loaded as a separate script file:

<script src="popup.js"></script>
始终不够爱げ你 2025-02-02 09:03:51

Reason

This does not work, because Chrome forbids any kind of inline code in extensions via Content Security政策。

不会执行内联JavaScript。此限制禁止内联&lt; script&gt; blocks 内联事件事件处理程序(例如&lt; button onclick =“ ...” ...“ ...”&gt;) 。

如何检测

这是否确实是问题,Chrome会在控制台中产生以下错误:

拒绝执行内联脚本,因为它违反了以下内容安全策略指令:“ script-src'self” chrome-extension-extension-resource:”。需要“不安全限制”关键字,hash('sha256 -...')或nonce('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事件中的包装。这样可以确保该元素在执行时存在。现在,添加脚本标签,例如,在&lt; head&gt;中添加文档的:

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

替代方案,如果您使用jQuery:

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

放松策略

q:该错误提到了方法允许内联代码。我不想 /不能更改我的代码,如何启用内联脚本?

a:尽管错误说的是 不能启用内联脚本

没有放宽限制执行内联JavaScript的机制。特别是,设置包含'Undafe-Inline''的脚本策略将无效。

更新:自Chrome 46以来

从Chrome 46开始,可以通过在策略中指定源代码的base64编码哈希来将内联脚本列入。该哈希必须由用过的哈希算法(SHA256,SHA384或SHA512)进行前缀。参见 hash> hash> hash for ;元素例如。

但是,我没有很容易看到使用此功能的理由,也不会启用诸如onclick =“ code”之类的内联属性。

Reason

This does not work, because Chrome forbids any kind of inline code in extensions via Content Security Policy.

Inline JavaScript will not be executed. This restriction bans both inline <script> blocks and inline event handlers (e.g. <button onclick="...">).

How to detect

If this is indeed the problem, Chrome would produce the following error in the console:

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' chrome-extension-resource:". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.

To access a popup's JavaScript console (which is useful for debug in general), right-click your extension's button and select "Inspect popup" from the context menu.

More information on debugging a popup is available here.

How to fix

One needs to remove all inline JavaScript. There is a guide in Chrome documentation.

Suppose the original looks like:

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

One needs to remove the onclick attribute and give the element a unique id:

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

And then attach the listener from a script (which must be in a .js file, suppose 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() {
  /* ... */
}

Note the wrapping in a DOMContentLoaded event. This ensures that the element exists at the time of execution. Now add the script tag, for instance in the <head> of the document:

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

Alternative if you're using jQuery:

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

Relaxing the policy

Q: The error mentions ways to allow inline code. I don't want to / can't change my code, how do I enable inline scripts?

A: Despite what the error says, you cannot enable inline script:

There is no mechanism for relaxing the restriction against executing inline JavaScript. In particular, setting a script policy that includes 'unsafe-inline' will have no effect.

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".

┊风居住的梦幻卍 2025-02-02 09:03:51

我遇到了同样的问题,并且不想重写代码,因此我编写了一个函数来修改代码并创建内联声明的事件:

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重新创建它们。

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.

拿命拼未来 2025-02-02 09:03:51

我决定发布我在情况下使用的示例。我尝试使用脚本替换DIV中的内容。我的问题是,Chrome没有识别 /没有运行该脚本。

更详细地说,我想做的是:单击链接,以及指向“读取”外部HTML文件的链接,将其加载到DIV部分中。

  • 我发现,通过将脚本放在Div的ID面前
    被称为,脚本没有用。
  • 如果脚本在另一个Div中,则它也无法使用
  • 必须使用document.addeventlistener('domcontentloaded',function',function(),

     &lt; Body&gt;
        &lt; aid = id_page href =“#love” onclick =“ load_services()”&gt;爱情&lt;/a&gt;
    
            &lt; script&gt;
                    //此脚本必须在正在调用的“ ID”下
                    //请勿将其转移到与呼叫者“ ID”的不同DIV
                    document.getElementById(“ id_page”)。addeventListener(“ click”,function(){
                    document.getElementById(“ Mainbody”).InnerHtml ='&lt; object data =“ services.html” class =“ loved_css_edit”; &gt;&lt;/object&gt;'; });
                &lt;/script&gt;
        &lt;/body&gt;
    
      &lt; div ID =“ mainbod” class =“ main_body”&gt;
            “当爱的链接将在此处加载外部HTML文件 
             点击。 “
      &lt;/div&gt;
     

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>
    
誰認得朕 2025-02-02 09:03:51

如前所述,由于安全原因,Chrome Extensions不允许使用内联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());
    }
}

As already mentioned, Chrome Extensions don't allow to have inline JavaScript due to security reasons so you can try this workaround as well.

HTML file

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

Or if you are having a Jquery file included then

window.onclick = function(event) {
    var target = event.target ;
    if(target.matches('.clickableBtn')) {
        alert($(target).text());
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文