简体   繁体   中英

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?

That particular site has monkeypatched appendChild , as you can see if you run

document.body.appendChild.toString()

into the console: it gives you

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

in return instead of [native code] , which means the native function has been overwritten.

Note that the patched prototype object is Element.prototype , but appendChild exists natively on Node.prototype , which remains unpatched:

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

You can .call the unpatched appendChild instead:

(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)

and then it will be appended successfully. ( typeof jQuery will then evaluate to function rather than undefined , and you can see that the correct URL is requested from the network tab)


If the site had patched it properly and made all references to Node.prototype.appendChild inaccessible, the only solution would be to run your own Javascript before the page's Javascript ran, which could be done using a userscript manager like Tampermonkey , @run-at document-start , and using instant script injection to save a reference to Node.prototype.appendChild before it gets overwritten.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM