问题描述:
项目需求使用photoswipe插件实现点击缩略图实现图片的预览,放大,轮播,下载保存等效果,图片存贮在AWS云服务器上,在开发过程发现使用photoswipe自带的下载功能会直接预览图片而非下载。
原因分析:
由于 photoswipe上自带的下载功能的原理实际是: 通过a标签的 "download"属性实现图片的下载,经过查阅发现a标签的"download"属性的特点 :
1.只适用于同源文件的下载
MDN中讲a标签的download的属性仅适用于同源URLs,但是它又可以使用 blob:URLs和 data:URLs 的形式
2.如果可以识别链接路径则直接打开则不会下载,
所以,由于开发项目中的代码存储在AWS云服务器,所以是跨域请求,则会出现只是预览图片而不能下载的问题.
解决方案:
1.可以通过修改服务器的文件的类型, 将其改为浏览器不能直接识别的链接 例如 (https://event.s3.ap-east-1.amazonaws.com/uat/46BF3C27-F537-4C13-8E5B-1EB1B05EBE38.zip) (不建议,因为缩略图需要显示图片,如此修改则不能显示缩略图,不符合项目需求)
2.使用canvas的blob:URLs来实现,并且修改服务器的配置让其允许跨域,
前端代码如下:
function saveAs(){
let src = 'https://event.s3.ap-east-1.amazonaws.com/uat/46BF3C27-F537-4C13-8E5B-1EB1B05EBE38'
var canvas = document.createElement('canvas');
var img = document.createElement('img');
img.onload = function(e) {
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0, img.width, img.height);
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
canvas.toBlob((blob)=>{
let link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'aaa';
link.click();
}, "image/jpeg");
}
img.setAttribute("crossOrigin",'Anonymous');
img.crossOrigin="Anonymous";
img.src = src;
}*/
补充问题:
通过方式二解决,并且服务器也已经设置了服务器端允许跨域的配置,但是再次访问发现仍然会出现跨域的问题,经过不断的排查发现是缓存或者是CDN导致的.
原因:
因为当浏览器第一次请求展示缩略图时,会直接去请求服务器端的资源,当然,服务器已经配置了允许跨域请求,所以可以获取到资源,图片可以展示,但是当点击预览的图片的下载按钮时,此时,该图片已经被缓存了,所以此时则不会再去请求服务器中的资源了,而是直接从缓存中直接拿资源,此时缓存并没有处理跨域的问题,所以就会导致再次出现跨域了.
最终解决方案:
可以直接使用非缓存的地址,防止缓存,直接从服务器获取img 的url ,具体做法:
可以在发送ajax请求时url=url+’?v=’+Math.random().toString() ,让其直接返回服务器端的资源.
修改 img.src = src;
为以下代码即可
img.src = src+'?v='+Math.random().toString();
最后也可参考下面链接,实现photoswipe图片预览时不可以长按调出系统"保存图片"的菜单.
个人项目中遇到的一点问题,希望对大家有所帮助.