动态导入script
JavaScript 代码:
<script>
function loadError (error) {
throw new URIError(`The script ${error.target.src} is not accessible.`)
}
function importScript (src, onLoad) {
var script = document.createElement('script')
script.onerror = loadError
script.async = false
if (onLoad) { script.onload = onLoad }
document.header.appendChild(script)
script.src = src
}
</script>
上面的方法动态加载js资源,注意,默认 append 到文档中的 script 会异步执行(可以理解为默认拥有 async 属性,如果需要加载的js按顺序执行,需要设置 async 为 false )
script 标签的 integrity 属性
<script crossorigin="anonymous" integrity="sha256-PJJrxrJLzT6CCz1jDfQXTRWOO9zmemDQbmLtSlFQluc=" src="https://assets-cdn.github.com/assets/frameworks-3c926bc6b24bcd3e820b3d630df4174d158e3bdce67a60d06e62ed4a515096e7.js"></script>
integrity 属性是资源完整性规范的一部分,它允许你为 script 提供一个 hash,用来进行验签,检验加载的JavaScript 文件是否完整。
integrity="sha256-PJJrxrJLzT6CCz1jDfQXTRWOO9zmemDQbmLtSlFQluc=" 告诉浏览器,使用sha256签名算法对下载的js文件进行计算,并与intergrity提供的摘要签名对比,如果二者不一致,就不会执行这个资源。
intergrity 的作用有:
减少由【托管在CDN的资源被篡改】而引入的XSS 风险;
减少通信过程资源被篡改而引入的XSS风险(同时使用https会更保险)
可以通过一些技术手段,不执行有脏数据的CDN资源,同时去源站下载对应资源;
注意:启用 SRI 策略后,浏览器会对资源进行 CORS 校验,这就要求被请求的资源必须同域,或者配置了 Access-Control-Allow-Origin 响应头;
script 标签的 crossorigin 属性
crossorigin 的属性值可以是 anonymous、use-credentials,如果没有属性值或者非法属性值,会被浏览器默认做anonymous。
crossorigin的作用有三个:
crossorigin 会让浏览器启用CORS访问检查,检查http相应头的 Access-Control-Allow-Origin
对于传统 script 需要跨域获取的js资源,控制暴露出其报错的详细信息
对于 module script ,控制用于跨域请求的凭据模式
我们在收集错误日志的时候,通常会在window上注册一个方法来监测所有代码抛出的异常:
JavaScript 代码:
window.addEventListener('error', function(msg, url, lineno, colno, error) {
var string = msg.toLowerCase()
var substring = "script error"
if (string.indexOf(substring) > -1){
alert('Script Error: See Browser Console for Detail')
} else {
var message = {
Message: msg,
URL: url,
Line: lineNo,
Column: columnNo,
'Error object': JSON.stringify(error)
}
// send error log to server
record(message)
}
return false
})
但是对于跨域js来说,只会给出很少的报错信息:'error: script error',通过使用 crossorigin 属性可以使跨域js暴露出跟同域js同样的报错信息。但是,资源服务器必须返回一个 Access-Control-Allow-Origin 的header,否则资源无法访问。
网友评论