在一个前端的职业生涯里,不可避免的会和一个叫作跨域的家伙打交道。那跨域的缘由、跨域的场景以及跨域的解决方案在这里我就不赘述了(若是想具体了解的能够参考这篇博文https://blog.csdn.net/qq_3812...)。我这边主要讲的是一种不太常见的跨域,就是浏览器的缓存跨域问题。css
浏览器缓存跨域,顾名思义是因为浏览器的缓存机制致使的一种跨域状况。这种跨域通常会出如今浏览器经过一些无视跨域的标签和css(如img、background-image)缓存了一些图片资源以后,当再次发起图片请求时(好比转base64等操做),就不会向服务器端请求数据,而是直接请求缓存数据,从而引发了跨域。这个时候即便服务端设置了Access-Control-Allow-Origin,但浏览器请求的是缓存,依旧会致使跨域的发生。html
我这边遇到的跨域场景是这样的,业务须要将一个有背景图片的div标签经过html2canvas这个工具保存为图片。现有的环境是:图片储存在腾讯云的cos上而且Access-Control-Allow-Origin中已添加请求源地址,html2canvas在执行的时候就会报出跨域的错误。前端
<div id="capture" style="width: 100px;height: 200px;background-image: url(https://cms-forum-prd-1255478381.cos.ap-shanghai.myqcloud.com/36dfcd29c313428f914c68f972b74d9f_1604570360_0050.png);background-size: contain;">占位文字</div>
html2canvas(document.querySelector("#capture"),{ useCORS: true }).then(canvas => { document.body.appendChild(canvas) });
当咱们知道跨域缘由的时候就明白如何去解决问题了。canvas
这种设置保证了浏览器在加载图片图片的时候不进行缓存,因此在第二次请求图片的时候,天然也是去cos上请求,从而避免了跨域的问题(固然,前提是cos已经设置了Access-Control-Allow-Origin)跨域
若是图片是在img标签里而不是做为background-image的样式,那么在图片的url上加上'?v=12345',其中12345用随机数替代好比Math.floor(Math.random(0,1)*1000)
等,但这种好像不太适用background-imagepromise
在使用html2canvas以前,将图片的url地址转换成base64,再进行操做。浏览器
function getBase64(url) { return new Promise((resolve, reject) => { var image = new Image(); image.src = `${url}?v=${Math.floor(Math.random(0,1)*1000)}`; image.onload = function () { var canvas = document.createElement("canvas"); canvas.width = image.width; canvas.height = image.height; var ctx = canvas.getContext("2d"); ctx.drawImage(image, 0, 0, image.width, image.height); var ext = image.src.substring(image.src.lastIndexOf(".") + 1).toLowerCase(); var dataURL = canvas.toDataURL("image/" + ext); resolve(dataURL) } }) }
注意事项1:在替换background-image的url时候,记得把'url()'也加上
注意事项2:上述代码中我只是提供了一种转换url为base64的方法,具体的替换只要操做一下dom,把原地址改为base64就好啦,注意他是个promise函数缓存
那么,这篇文章就暂时先写到这吧,对了,还要顺带填一个坑,就是safari在background-image的url为空的状况下会默认加上当前的域名地址,可是chorme默认为空~~~~服务器