前端填坑之浏览器缓存跨域

引言

在一个前端的职业生涯里,不可避免的会和一个叫作跨域的家伙打交道。那跨域的缘由、跨域的场景以及跨域的解决方案在这里我就不赘述了(若是想具体了解的能够参考这篇博文https://blog.csdn.net/qq_3812...)。我这边主要讲的是一种不太常见的跨域,就是浏览器的缓存跨域问题。css

1、什么是浏览器的缓存跨域

浏览器缓存跨域,顾名思义是因为浏览器的缓存机制致使的一种跨域状况。这种跨域通常会出如今浏览器经过一些无视跨域的标签和css(如img、background-image)缓存了一些图片资源以后,当再次发起图片请求时(好比转base64等操做),就不会向服务器端请求数据,而是直接请求缓存数据,从而引发了跨域。这个时候即便服务端设置了Access-Control-Allow-Origin,但浏览器请求的是缓存,依旧会致使跨域的发生。html

2、我所遇到的缓存跨域场景

我这边遇到的跨域场景是这样的,业务须要将一个有背景图片的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)
});

image

3、解决方案

当咱们知道跨域缘由的时候就明白如何去解决问题了。canvas

一、cos上的资源设置no-cache

这种设置保证了浏览器在加载图片图片的时候不进行缓存,因此在第二次请求图片的时候,天然也是去cos上请求,从而避免了跨域的问题(固然,前提是cos已经设置了Access-Control-Allow-Origin跨域

二、图片url加参数

若是图片是在img标签里而不是做为background-image的样式,那么在图片的url上加上'?v=12345',其中12345用随机数替代好比Math.floor(Math.random(0,1)*1000)等,但这种好像不太适用background-imagepromise

三、使用base64来替代图片url

在使用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函数缓存

4、结尾

那么,这篇文章就暂时先写到这吧,对了,还要顺带填一个坑,就是safari在background-image的url为空的状况下会默认加上当前的域名地址,可是chorme默认为空~~~~服务器

相关文章
相关标签/搜索