zoukankan      html  css  js  c++  java
  • 【JavaScript】使用url下载文件,解决chrome浏览器自动识别图片打开问题。

    前两天做的一个文件下载,使用文件存储地址url去下载,不需要打开文件。使用新建a标签,触发点击事件来进行下载。

     downloadNormalFile(src, filename) {
                    var link = document.createElement('a');
                    link.setAttribute("download", filename);
                    link.href = src;
                    document.body.appendChild(link);//添加到页面中,为兼容Firefox浏览器
                    link.click();
                    document.body.removeChild(link);//从页面移除
                },

    新建a标签,设置href为文件存储地址,添加html5的新属性download,然后触发a标签的click事件即可。但是在火狐浏览器中a标签需要添加到页面中才能触发事件下载。所以添加到body中后又移除。


    上面是通常情况下的做法,我遇到一个问题,在chrome浏览器中当文件是图片时,浏览器不会下载,而是打开图片链接显示。网上查找了很多方法,采用将utl转换为base64格式,然后触发下载,这样浏览器不会自动识别url打开显示。

    ImgtodataURL(url, filename, fileType) {
                    this.getBase64(url, fileType, (_baseUrl) => {
                        // 创建隐藏的可下载链接
                        var eleLink = document.createElement('a');
                        eleLink.download = filename;
                        eleLink.style.display = 'none';
                        // 图片转base64地址
                        eleLink.href = _baseUrl;
                        // 触发点击
                        document.body.appendChild(eleLink);
                        eleLink.click();
                        // 然后移除
                        document.body.removeChild(eleLink);
                    });
    
                },
                getBase64(url, fileType, callback) {
                    //通过构造函数来创建的 img 实例,在赋予 src 值后就会立刻下载图片
                    var Img = new Image(),
                        dataURL = '';
                    Img.src = url;
                    Img.setAttribute("crossOrigin", 'Anonymous');
                    Img.onload = function () { //要先确保图片完整获取到,这是个异步事件
                        var canvas = document.createElement("canvas"), //创建canvas元素
                            width = Img.width, //确保canvas的尺寸和图片一样
                            height = Img.height;
                        canvas.width = width;
                        canvas.height = height;
                        canvas.getContext("2d").drawImage(Img, 0, 0, width, height); //将图片绘制到canvas中
                        dataURL = canvas.toDataURL('image/' + fileType); //转换图片为dataURL
                        callback ? callback(dataURL) : null;
                    };
                }

    getbase64采用canvas绘制图片后采用callback方法调用异步加载onload方法获取到的dataurl,然后再新建a标签触发下载。


    到上一步,基本解决了问题,但是在Edge浏览器中,下载图片报错了。

    SCRIPT5022: SecurityError

    因为在Edge中浏览器用户代理值为:

    包含chrome,所以在判断浏览器的时候将Edge浏览器也判断为了chrome浏览器,执行了getbase64转换了url。故作判断时需要排除这种情况。

    isImageInChromeNotEdge(fType) {
                    let bool = false;
                    if (window.navigator.userAgent.indexOf("Chrome") !== -1 && window.navigator.userAgent.indexOf("Edge") === -1)
                        (fType === "jpg" || fType === "gif" || fType === "png" || fType === "bmp" || fType === "jpeg" || fType === "svg") && (bool = true);
                        return bool;
                },

    最后从获取到url后下载的操作完整代码为:

        download(src,row){    //row.ITEMNAME为文件名称,src为文件存储地址            
            if (this.isImageInChromeNotEdge(fType)) {//判断是否为chrome里的图片 this.ImgtodataURL(src, row.ITEMNAME, fType); } else { this.downloadNormalFile(src, row.ITEMNAME); } }, isImageInChromeNotEdge(fType) { let bool = false; if (window.navigator.userAgent.indexOf("Chrome") !== -1 && window.navigator.userAgent.indexOf("Edge") === -1) (fType === "jpg" || fType === "gif" || fType === "png" || fType === "bmp" || fType === "jpeg" || fType === "svg") && (bool = true); return bool; }, downloadNormalFile(src, filename) { var link = document.createElement('a'); link.setAttribute("download", filename); link.href = src; document.body.appendChild(link);//添加到页面中,为兼容Firefox浏览器 link.click(); document.body.removeChild(link);//从页面移除 }, ImgtodataURL(url, filename, fileType) { this.getBase64(url, fileType, (_baseUrl) => { // 创建隐藏的可下载链接 var eleLink = document.createElement('a'); eleLink.download = filename; eleLink.style.display = 'none'; // 图片转base64地址 eleLink.href = _baseUrl; // 触发点击 document.body.appendChild(eleLink); eleLink.click(); // 然后移除 document.body.removeChild(eleLink); }); }, getBase64(url, fileType, callback) { //通过构造函数来创建的 img 实例,在赋予 src 值后就会立刻下载图片 var Img = new Image(), dataURL = ''; Img.src = url; Img.setAttribute("crossOrigin", 'Anonymous'); Img.onload = function () { //要先确保图片完整获取到,这是个异步事件 var canvas = document.createElement("canvas"), //创建canvas元素 width = Img.width, //确保canvas的尺寸和图片一样 height = Img.height; canvas.width = width; canvas.height = height; canvas.getContext("2d").drawImage(Img, 0, 0, width, height); //将图片绘制到canvas中 dataURL = canvas.toDataURL('image/' + fileType); //转换图片为dataURL callback ? callback(dataURL) : null; }; }
  • 相关阅读:
    祝贺我的博客訪问量过万(訪问量:10260次)
    【LeetCode-面试算法经典-Java实现】【107-Binary Tree Level Order Traversal II(二叉树层序遍历II)】
    Hibernate之HQL检索(查询)方式
    使用Nexus搭建Maven仓库
    poj2151之概率DP
    《从零開始学Swift》学习笔记(Day 71)——Swift与C/C++混合编程之数据类型映射
    D3D 点列练习
    poj 1733 Parity game
    命令行參数
    高速乘法
  • 原文地址:https://www.cnblogs.com/qiuyueding/p/9455334.html
Copyright © 2011-2022 走看看