需求:因为有多个html页面引用了同一个script标签(引入地图用的js),想将html里的script标签的src弄成可配置的,不写死src,可以在config.js里配置,方便上线可更换地图的src。
<script type="text/javascript" charset="UTF-8"
src="http://129.28.123.253:8080/api/init.js?v=1.0&appSecret=1c27d0b6326d0a708d83e46a09e8f5af&appKey=f8052cf8524bfef19d39b976aba7f7e">
</script>
修改思路:动态创建script标签,设置script的src为config.js里的src值。
var script = document.createElement('script')
script.src = mapSrc;
document.appendChild(script)
这时候就遇到问题了,控制台报错:
Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.
大意是说异步加载的外部js不能使用document.write方法往页面写东西,然后我打开了这个链接,发现这个js文件里果然有好几处使用了document.write()来添加script标签和css文件。
然后,经过上网搜索,我尝试了将动态创建的script标签的async和defer属性设置为false,发现还是报错require is not defined,原因是后面的js代码中有个require函数,这个函数应该是我要引入的标签里的函数。将async设置为false都不能将改变外部js的异步加载,说明动态创建的script标签是异步加载的。后来还尝试了在script的onload事件回调中执行我的js代码,发现还是报错说异步加载的js不能使用document.write方法。
解决:后来突然看到这种动态拼接script标签字符串的写法:
document.write(`<script type="text/javascript" charset="UTF-8"
src="${mapSrc}">
</scr${''}ipt>`)
发现能够加载成功并执行完后面的代码,说明这个方法创建的script标签是同步加载js的,这样后面的js代码的require才能调用。此时控制台也出现了一行警告:
大意是说[弃用],同步的ajax请求在主线程中不被提倡使用,因为有损用户体验。
[Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.