在一個前端的職業生涯裏,不可避免的會和一個叫作跨域的傢伙打交道。那跨域的緣由、跨域的場景以及跨域的解決方案在這裏我就不贅述了(若是想具體瞭解的能夠參考這篇博文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默認爲空~~~~服務器