https页面加载http资源的解决方法

简介: https页面加载http资源的解决方法

image.png

@[toc]

1.报错如图

image.png

2.项目背景

我们的项目采用的全是https请求,而使用第三方文件管理器go-fastdfs,该文件管理器返回的所有下载文件的请求全是http开头的,比如http://10.110.38.253:11014/group1/batchImportData/组 (26).xlsx,然而在https请求下使用http的请求就会报如上图的错误,且不能把文件下载请求http改为https,因为修改后会查询不到文件。所以必须只能采用http的请求且想让功能实现。

image.png

注意点1:我们公司项目请求协议前缀必须是https的,执行http的无效

注意点2:这种第三方返回的文件下载路径http://10.110.38.253:11014/group1/batchImportData/组 (26).xlsx,是可以直接放在浏览器上直接下载的,具体请看如图
image.png

3.网上的解决方案

可以先看下其他人的博客,但是方案对我目前公司项目无效

1.https页面加载http资源的解决方法

2.分享 4个解决 https页面加载http资源报错的方法

问题:里面的方案为啥对我公司的项目无效?

答案:

  • 针对修改协议前缀的方案,我们的必须得是https的才行,其他无效。
  • 针对使用 iframe 的方案,因为没用过,且感觉项目引入会很费事且庞杂,所以当时没考虑该方案。
  • 针对自动升级方案(也就是说把第三方文件管理器go-fastdfs配置文件改了,由http协议改为https协议),该方案真对我的项目不行,因为我的公司有很多老项目都是用这个文件管理器go-fastdfs,如果把协议改了,不清楚对其他服务会不会有影响,所以轻易不能动。

综上所述:上面的方案我一个都不能用,所以我需要另想他法。

4.我的最终解决方案

接下来说下我最终想到的方便且容易上手的解决方案:那就是采用http工具执行url -> 然后把文件先下载到项目所在服务器的临时目录内 -> 然后再以读取普通文件路径的方式加载成File -> 再然后以流的方式输出给客户端弹窗另存为保存 -> 最后关闭流并删除服务器路径下的临时文件。

pom.xml

<dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>3.17</version>
</dependency>
<dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.4.1</version>
</dependency>
<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.17</version>
</dependency>

前端js代码

//批量管理-下载批量导入数据
function downloadBatchImportDataTaskActionColumn(taskId) {
   
    var language = 'zh';
    if(Cookies.get("language") != null &&  Cookies.get("language") != "")
    {
   
        language = Cookies.get("language") ;
    }
    var url = prefix + "/downloadBatchImportData?language=" + language;
    var form = $("<form></form>").attr("action", url).attr("method", "post");
    form.append($("<input></input>").attr("type", "hidden").attr("name", "taskId").attr("value", taskId));
    form.appendTo('body').submit().remove();
}

后端Controller代码

/**
     * 下载批量导入数据
     * 流程:
     *      查询数据库判断filedownLink字段是否为空
     *          为空:则代表旧数据,没有gofd对应的下载文件地址,因此把模板文件返回给客户端
     *          不为空:则代表gofd已经上传了对应的批量导入文件,且数据库中保存地址链接
     *              通过filedownLink封装成FiLE
     *                  判断File在临时目录内是否存在
     *                      存在:则直接返回给客户端,最后再把服务器临时目录内文件删除
     *                      不存在:则通过http工具调用filedownLink封装成File,将文件写入tempFilePath临时目录内,再把文件File返回给客户端,最后再把服务器临时目录内文件删除
     * @param req req
     * @param response response
     */
    @RequestMapping(value = "/downloadBatchImportData")
    public void downloadBatchImportData(HttpServletRequest req, HttpServletResponse response) {
   
        logger.info("-downloadBatchImportData-begin");
        String taskId = req.getParameter("taskId");
        OutputStream os = null;
        InputStream io = null;
        String tempFilePath = TEMP_FILE_PATH;
        String fileName = "";
        String language = req.getParameter("language");
        Workbook wb = null;

        try {
   
            ImpExpTaskDetail impExpTaskDetail = isvcBatchTaskServiceMicro.selectTaskDetailByTaskId(taskId);
            String filedownLink = impExpTaskDetail.getLink();
            if (org.springframework.util.StringUtils.isEmpty(filedownLink)) {
   
                fileName = MessageUtils.message("batch.template") + ".xlsx";
                String templateFileName = BatchConstant.DOWNAD_TEMPLATE_NAME + "_" + language + BatchConstant.EXTENSION_XLSX;
                SysUser sysUser = ShiroUtils.getSysUser();
                logger.info("-downloadBatchImportData-taskId:{},language:{}", taskId, language);
                if (isysUserService.get36kType(sysUser.getUserId()) == Poc36kEnum.POC6K.getType()) {
   
                    templateFileName = BatchConstant.DOWNAD_TEMPLATE_NAME + "6k" + "_" + language + BatchConstant.EXTENSION_XLSX;
                }
                File templateFile = org.springframework.util.ResourceUtils.getFile("classpath:" + templateFileName);
                logger.info("-Template file exist!,templateFileName:{}", templateFileName);
                io = new FileInputStream(templateFile);
                wb = new XSSFWorkbook(io);
            } else {
   
                fileName = StringUtils.subscribeNameString(filedownLink);
                File file = ResourceUtils.getFile(String.join(File.separator, tempFilePath, fileName));
                if (!file.exists()) {
   
                    String begin = DateUtil.now();
                    DateTime beginTime = DateUtil.parse(begin);
                    long download = HttpUtil.downloadFile(filedownLink, FileUtil.file(tempFilePath, fileName), new StreamProgress() {
   
                        @Override
                        public void start() {
   
                            logger.info("开始下载,时间为:" + begin);
                        }

                        @Override
                        public void progress(long progressSize) {
   
                            logger.info("已下载:{}", FileUtil.readableFileSize(progressSize));
                        }

                        @Override
                        public void finish() {
   
                            String end = DateUtil.now();
                            DateTime endTime = DateUtil.parse(end);
                            long between = DateUtil.between(beginTime, endTime, DateUnit.MS);
                            logger.info("下载完成,用时:" + DateUtil.formatBetween(between, BetweenFormatter.Level.SECOND));
                        }
                    });
                }

                io = new FileInputStream(file);
                wb = new XSSFWorkbook(io);
            }
            logger.info("-tempFilePath:{},fileName:{}", tempFilePath, fileName);
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
            wb.write(response.getOutputStream());
        } catch (IOException e) {
   
            logger.error("-downloadBatchImportData error:{}", e.getMessage());
        } finally {
   
            if (os != null) {
   
                try {
   
                    os.close();
                } catch (IOException e) {
   
                    logger.error("-OutputStream error:{}", e.getMessage());
                }
            }
            if (io != null) {
   
                try {
   
                    io.close();
                } catch (IOException e) {
   
                    logger.error("-InputStream error:{}", e.getMessage());
                }
            }
            if (Optional.ofNullable(tempFilePath).isPresent()) {
   
                // 强制删除临时文件
                boolean isDelete = com.hytalk.util.FileUtil.delFile(new File(tempFilePath));
                logger.info("-downloadBatchImportData 强制删除临时文件 , filePath: {} , isDelete : {} ", tempFilePath, isDelete);
            }
        }
    }

FileUtil工具类

import java.io.File;

/**
 * 文件工具
 * @Author 211145187
 * @Date 2023/4/19 14:27
 **/
public class FileUtil {
   

    /**
     * 删除文件
     * @param file 文件
     * @return boolean
     */
    public static boolean delFile(File file) {
   
        if (!file.exists()) {
   
            return false;
        }
        if (file.isDirectory()) {
   
            File[] files = file.listFiles();
            for (File f : files) {
   
                delFile(f);
            }
        }
        return file.delete();
    }
}

StringUtils工具类

/**
 * 字符串工具
 * @author 211145187
 * @Date: 2021/11/11 16:11
 **/
public class StringUtils {
   
    /**
     * 截取url地址中的名称,比如路径地址为“http://10.110.38.253:11014/group1/batchImportData/组 (26).xlsx”,最后截取的名称为“组 (26).xlsx”
     * @param str 原字符串
     * @return 截取后的字符串
     */
    public static String subscribeNameString(String str) {
   
        if (str.lastIndexOf("/") > -1) {
   
            str = str.substring(str.lastIndexOf("/") + 1);
        }
        return str;
    }
}

说明:

只在意我的思路流程即可,至于工具类或者查数据库数据代码啥的就不复制粘贴了。

目录
相关文章
|
3天前
|
弹性计算 双11 开发者
阿里云ECS“99套餐”再升级!双11一站式满足全年算力需求
11月1日,阿里云弹性计算ECS双11活动全面开启,在延续火爆的云服务器“99套餐”外,CPU、GPU及容器等算力产品均迎来了全年最低价。同时,阿里云全新推出简捷版控制台ECS Lite及专属宝塔面板,大幅降低企业和开发者使用ECS云服务器门槛。
|
21天前
|
存储 弹性计算 人工智能
阿里云弹性计算_通用计算专场精华概览 | 2024云栖大会回顾
阿里云弹性计算产品线、存储产品线产品负责人Alex Chen(陈起鲲)及团队内多位专家,和中国电子技术标准化研究院云计算标准负责人陈行、北京望石智慧科技有限公司首席架构师王晓满两位嘉宾,一同带来了题为《通用计算新品发布与行业实践》的专场Session。本次专场内容包括阿里云弹性计算全新发布的产品家族、阿里云第 9 代 ECS 企业级实例、CIPU 2.0技术解读、E-HPC+超算融合、倚天云原生算力解析等内容,并发布了国内首个云超算国家标准。
阿里云弹性计算_通用计算专场精华概览 | 2024云栖大会回顾
|
3天前
|
人工智能 弹性计算 文字识别
基于阿里云文档智能和RAG快速构建企业"第二大脑"
在数字化转型的背景下,企业面临海量文档管理的挑战。传统的文档管理方式效率低下,难以满足业务需求。阿里云推出的文档智能(Document Mind)与检索增强生成(RAG)技术,通过自动化解析和智能检索,极大地提升了文档管理的效率和信息利用的价值。本文介绍了如何利用阿里云的解决方案,快速构建企业专属的“第二大脑”,助力企业在竞争中占据优势。
|
1天前
|
人工智能 自然语言处理 安全
创新不设限,灵码赋新能:通义灵码新功能深度评测
自从2023年通义灵码发布以来,这款基于阿里云通义大模型的AI编码助手迅速成为开发者心中的“明星产品”。它不仅为个人开发者提供强大支持,还帮助企业团队提升研发效率,推动软件开发行业的创新发展。本文将深入探讨通义灵码最新版本的三大新功能:@workspace、@terminal 和 #team docs,分享这些功能如何在实际工作中提高效率的具体案例。
|
7天前
|
负载均衡 算法 网络安全
阿里云WoSign SSL证书申请指南_沃通SSL技术文档
阿里云平台WoSign品牌SSL证书是由阿里云合作伙伴沃通CA提供,上线阿里云平台以来,成为阿里云平台热销的国产品牌证书产品,用户在阿里云平台https://www.aliyun.com/product/cas 可直接下单购买WoSign SSL证书,快捷部署到阿里云产品中。
1850 6
阿里云WoSign SSL证书申请指南_沃通SSL技术文档
|
10天前
|
Web App开发 算法 安全
什么是阿里云WoSign SSL证书?_沃通SSL技术文档
WoSign品牌SSL证书由阿里云平台SSL证书合作伙伴沃通CA提供,上线阿里云平台以来,成为阿里云平台热销的国产品牌证书产品。
1789 2
|
19天前
|
编解码 Java 程序员
写代码还有专业的编程显示器?
写代码已经十个年头了, 一直都是习惯直接用一台Mac电脑写代码 偶尔接一个显示器, 但是可能因为公司配的显示器不怎么样, 还要接转接头 搞得桌面杂乱无章,分辨率也低,感觉屏幕还是Mac自带的看着舒服
|
26天前
|
存储 人工智能 缓存
AI助理直击要害,从繁复中提炼精华——使用CDN加速访问OSS存储的图片
本案例介绍如何利用AI助理快速实现OSS存储的图片接入CDN,以加速图片访问。通过AI助理提炼关键操作步骤,避免在复杂文档中寻找解决方案。主要步骤包括开通CDN、添加加速域名、配置CNAME等。实测显示,接入CDN后图片加载时间显著缩短,验证了加速效果。此方法大幅提高了操作效率,降低了学习成本。
5386 15
|
13天前
|
人工智能 关系型数据库 Serverless
1024,致开发者们——希望和你一起用技术人独有的方式,庆祝你的主场
阿里云开发者社区推出“1024·云上见”程序员节专题活动,包括云上实操、开发者测评和征文三个分会场,提供14个实操活动、3个解决方案、3 个产品方案的测评及征文比赛,旨在帮助开发者提升技能、分享经验,共筑技术梦想。
1139 152
|
21天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1585 14