Reputation: 1440
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?
Upvotes: 3
Views: 244
Reputation: 370949
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.
Upvotes: 2