兼容IE浏览器下载文件

普通的<download>标签在谷歌和其他浏览器上都没问题,但是项目中,用户有很多是使用IE浏览器的,版本是11.1,下载PDF功能就失效,怎么都不行,搞了很久,用微软说明的Blob搭配window.navigator.msSaveOrOpenBlob或window.navigator.msSaveBlob函数可以解决。

步骤:

1.前端把pdf文件链接地址传到后台,后台下载转成流返回给前端,
2、前端再保存成为文件

**

前端:

**

</script>

// 下载 pdf  pdfSrc为pdf的网络地址,格式为https:xxxxx/xx.pdf
function getDownLoadPdf(pdfSrc){
    event.stopPropagation()
    if (!!window.ActiveXObject || "ActiveXObject" in window){
        //是 IE 浏览器
        $.ajax({
            type : 'GET',
            async : false,
            url : '${request.contextPath}/public/downLoadPdf?pdfSrc='+pdfSrc,
            success : function(reponse) {

                var code = reponse.replace(/[\n\r]/g, '');
                var raw = window.atob(code);
                let rawLength = raw.length;
                //转换成pdf.js能直接解析的Uint8Array类型
                let uInt8Array = new Uint8Array(rawLength);
                for (let i = 0; i < rawLength; ++i) {
                    uInt8Array[i] = raw.charCodeAt(i);
                }
                //获取到了blob对象
                let blob=new Blob([uInt8Array], {type: 'application/pdf'});
                var uuid = getUuid().replace("-","");
                var fileName=uuid+'.pdf';
                //打开或保存
                window.navigator.msSaveOrOpenBlob(blob, fileName);
                //只保存
               // window.navigator.msSaveBlob(blob, fileName);
                layer.close(index);
            },
            error : function(xhr, type) {
                layer.close(index);

            }
        });

    }else{
        var index = layer.msg('下载中', {
            icon: 16,
            shade: 0.01,
            time: 1000 * 10,
            offset: ['50%', '25%'],
        });

        $.ajax({
            type : 'GET',
            async : false,
            url : '${request.contextPath}/public/downLoadPdf?pdfSrc='+pdfSrc,
            success : function(reponse) {

                var code = reponse.replace(/[\n\r]/g, '');
                var raw = window.atob(code);
                let rawLength = raw.length;
                //转换成pdf.js能直接解析的Uint8Array类型
                let uInt8Array = new Uint8Array(rawLength);
                for (let i = 0; i < rawLength; ++i) {
                    uInt8Array[i] = raw.charCodeAt(i);
                }
                //获取到了blob对象
                let blob=new Blob([uInt8Array], {type: 'application/pdf'});
                //获取当前url,直接放到iframe就能用,下载同理
                let blobURL = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.style.display = 'none';
                a.href = blobURL;
                a.download = '';
                document.body.appendChild(a);
                a.click();
                window.URL.revokeObjectURL(blobURL);
                document.body.removeChild(a)
                layer.close(index);
            },
            error : function(xhr, type) {
                layer.close(index);

            }
        });
    }
}


function getUuid() {
    var s = [];
    var hexDigits = "0123456789abcdef";
    for (var i = 0; i < 36; i++) {

        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }
    s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
    s[8] = s[13] = s[18] = s[23] = "-";

    var uuid = s.join("");
    return uuid;
}
</script>

后台代码

省略了controller,自己写一个

public String downloadPdfAndEncoder(String fileUrl) {
        logger.info("开始下载并转换pdf文件");
        Base64.Encoder encoder = Base64.getEncoder();
        DataInputStream in = null;
        BufferedInputStream bin = null;
        ByteArrayOutputStream baos = null;
        BufferedOutputStream bout = null;
        try {
            if(fileUrl.contains("https://")) {
                SSLContext sslcontext = SSLContext.getInstance("SSL", "SunJSSE");
                sslcontext.init(null, new TrustManager[]{new X509TrustUtiil()}, new java.security.SecureRandom());
                URL url = new URL(fileUrl);
                HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {
                    public boolean verify(String s, SSLSession sslsession) {
                        System.out.println("WARNING: Hostname is not matched for cert.");
                        return true;
                    }
                };
                HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);
                HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
                HttpsURLConnection urlCon = (HttpsURLConnection) url.openConnection();
                urlCon.setConnectTimeout(6000);
                urlCon.setReadTimeout(6000);
                int code = urlCon.getResponseCode();
                if (code != HttpURLConnection.HTTP_OK) {
                    throw new Exception("文件读取失败");
                }
                in = new DataInputStream(urlCon.getInputStream());
            } else {
                URL url = new URL(fileUrl);
                // 创建链接
                HttpURLConnection urlCon = (HttpURLConnection) url.openConnection();
                urlCon.setRequestMethod("GET");
                urlCon.setConnectTimeout(5000);
                in = new DataInputStream(urlCon.getInputStream());
            }
            //在文件输出流上安装节点流(更大效率读取)
            bin = new BufferedInputStream(in);
            // 创建一个新的 byte 数组输出流,它具有指定大小的缓冲区容量
            baos = new ByteArrayOutputStream();
            //创建一个新的缓冲输出流,以将数据写入指定的底层输出流
            bout = new BufferedOutputStream(baos);
            byte[] buffer = new byte[1024];
            int len = bin.read(buffer);
            while(len != -1){
                bout.write(buffer, 0, len);
                len = bin.read(buffer);
            }
            //刷新此输出流并强制写出所有缓冲的输出字节,必须这行代码,否则有可能有问题
            bout.flush();
            byte[] bytes = baos.toByteArray();
//            //sun公司的API
//            return encode.encodeBuffer(bytes).trim();
            //apache公司的API
            //return Base64.encodeBase64String(bytes);
            logger.info("下载并转换pdf文件完成");
            return encoder.encodeToString(bytes);
        } catch (Exception e) {
            logger.info("开始下载并转换pdf失败");
            e.printStackTrace();
        } finally {
            try {
                in.close();
                bin.close();
                //关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException
                //baos.close();
                bout.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值