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

引言

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

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

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

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

我这边遇到的跨域场景是这样的,业务需要将一个有背景图片的div标签通过html2canvas这个工具保存为图片。现有的环境是:图片储存在腾讯云的cos上并且Access-Control-Allow-Origin中已添加请求源地址,html2canvas在执行的时候就会报出跨域的错误。

占位文字
html2canvas(document.querySelector("#capture"),{
    useCORS: true
}).then(canvas => {
    document.body.appendChild(canvas)
});

image

三、解决方案

当我们知道跨域原因的时候就明白如何去解决问题了。

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

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

2、图片url加参数

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

3、使用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函数

四、结尾

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

你可能感兴趣的:(缓存,跨域,html2canvas)