首页 > 解决方案 > Injecting jQuery using bookmarklet not working on a page

问题描述

I was trying to use this bookmarklet:

javascript:void((function(doc){if(typeof jQuery=='undefined'){var script_jQuery=document.createElement('script');script_jQuery.setAttribute('src','https://code.jquery.com/jquery-latest.min.js');document.body.appendChild(script_jQuery);console.log('jQuery included ^_^');}else{console.log('jQuery already included ...');}})(document));

to inject jQuery into this page:

https://cn.bing.com/dict/?mkt=zh-cn&q=test

I opened the page, then opened developer console(I'm using Chrome), switched to network tab, then clicked on the bookmarklet, I noticed that Chrome didn't request https://code.jquery.com/jquery-latest.min.js, instead it requested the following url:

https://cn.bing.com/fd/ls/l?IG=EE977A4E38924F57B34A1371C04323C1&Type=Event.ClientInst&DATA=[{%22T%22:%22CI.AntiMalware%22,%22FID%22:%22CI%22,%22Name%22:%22AC%22,%22Text%22:%22S%3Ahttps%3A//code.jquery.com/jquery-latest.min.js%22}]

Does anyone know why the bookmarklet doesn't work on this page? how is this page redirecting the request?

标签: javascriptjqueryhtml

解决方案


那个特定的站点有猴子补丁appendChild,你可以看到如果你运行

document.body.appendChild.toString()

进入控制台:它给你

function(n){return t(n,"AC")?u.apply(this,arguments):null}

作为回报而不是[native code],这意味着本机函数已被覆盖。

请注意,修补后的原型对象是Element.prototype,但appendChild本机存在于 上Node.prototype,它仍然未修补:

Node.prototype.appendChild.toString()
// gives function appendChild() { [native code] }

您可以改为.call未修补:appendChild

(function(doc) {
  if (typeof jQuery == 'undefined') {
    var script_jQuery = document.createElement('script');
    script_jQuery.setAttribute('src', 'https://code.jquery.com/jquery-latest.min.js');
    Node.prototype.appendChild.call(
      document.body,
      script_jQuery
    );
    console.log('jQuery included ^_^');
  } else {
    console.log('jQuery already included ...');
  }
})(document)

然后它将成功附加。(typeof jQuery然后将评估为function而不是undefined,您可以看到从网络选项卡请求正确的 URL)


如果该站点已对其进行了适当的修补并使所有引用都无法访问,则唯一的解决方案是在页面的 Javascript 运行之前Node.prototype.appendChild运行您自己的 Javascript,这可以使用像Tampermonkey这样的用户脚本管理器来完成,并使用即时脚本注入来保存在它被覆盖之前引用。@run-at document-startNode.prototype.appendChild


推荐阅读