当前位置: 首页 > news >正文

下载文件,浏览器阻止不安全下载

背景:

在项目开发中,遇到需要下载文件的情况,文件类型可能是图片、excell表、pdf、zip等文件类型,但浏览器会阻止不安全的下载链接。

效果展示:

下载文件的两种方式: 

一、根据接口的相对url,拼接成完整路径下载

这串完整的下载路径是:

开发预留

在浏览器访问,图片如下:

 结果分析:

直接在浏览器就可以直接访问,可见这个文件没有加密,是不安全的。

 还有一个原因是实际情况,根据接口的url直接下载的。另外一种导出下载,是发起网络请求的,接收后台传给前端的二进制流之前需要先设置responseType为blob,否则默认会以json获取,下载下来的文件打开会提示文件已损坏。是发起网络请求的,并且后端接口返回的response头的content-type也是对应的类型,我的这里是application/vnd.ms-excel;charset=UTF-8。

二、网络接口,导出excell表格 

实现效果:

导出接口: 

这个接口返回的数据在控制台打印:

备注:控制台输出的可以看到是个正确的Blob对象,这就说明我们的配置是对的。 

实现思路【重点】:

导出接口传参给后端,后端对请求到的数据经过后端拼接,然后输出二进制流文件,然后给前端返回,前端直接下载。

需要注意几点:

1.前端请求需要携带请求体,config里面要带上responseType: 'blob'。举例:

    //导出文件【渡船管理】

    exportCrewInfoFile(params) {

        return request.Get("/data/ferryShip/download?", params, {

            headers: {

                "Content-Type": "application/json",

            },

            responseType: 'blob',

        });

    },

所以我们接收后台传给前端的二进制流之前需要先设置responseType为blob,否则默认会以json获取,下载下来的文件打开会提示文件已损坏。

2.后端最好也要配置response头的content-type为对应的类型。

3.需要给这个Blob对象设置一个type,这个type表明改Blob对象所包含数据的MIME类型。如果类型未知,则该值为空字符串。例如:type: "application/vnd.ms-excel",

/**

 *

 * @param {*} res 接口返回的文件流

 */

export const dowloadFileUrl = (res) => {

  console.log(res)

  const fileNames = res.headers['content-disposition']

  if (fileNames) {

      //解码

      const fileName = decodeURIComponent(fileNames.match(/=(.*)$/)[1])

      // 处理返回的文件流

      const content = res.data

      const blob = new Blob([content], {

          // type: res.data.type||"application/vnd.ms-excel",

          type: res.data.type||"application/octet-stream; charset=utf-8"

      });

      if ('download' in document.createElement('a')) {

          //非IE下载

          const a = document.createElement('a') //创建一个a标签

          a.download = fileName //指定文件名称

          a.style.display = 'none' //页面隐藏

          a.href = URL.createObjectURL(blob) // href用于下载地址

          document.body.appendChild(a) //插到页面上

          a.click() //通过点击触发

          URL.revokeObjectURL(a.href) //释放URL 对象

          document.body.removeChild(a) //删掉a标签

      } else {

          //IE10 + 下载

          navigator.msSaveBlob(blob, fileName)

      }

  }

}

三、下载文件的两种方式的对比

实现代码:

代码1:

    if (!data.file) {ElMessage.error("文件不存在!");return;}const url = BASEUrl + "/file/" + data.file;//拼接下载地址const a = document.createElement("a"); //创建一个a标签a.download = data.name; //指定文件名称a.style.display = "none"; //页面隐藏a.href = url; // href用于下载地址document.body.appendChild(a); //插到页面上a.click(); //通过点击触发URL.revokeObjectURL(a.href); //释放URL 对象document.body.removeChild(a); //删掉a标签

代码2: 

/**** @param {*} fileContent 文件本体* @param {*} _fileName 自定义文件名*/
export const exportFileUtil = (fileContent, _fileName) => {const content = fileContent;const blob = new Blob([content], {type: fileContent.type || "application/octet-stream; charset=utf-8",});const fileName = _fileName;if ("download" in document.createElement("a")) {//非IE下载const a = document.createElement("a"); //创建一个a标签a.download = fileName; //指定文件名称a.style.display = "none"; //页面隐藏a.href = URL.createObjectURL(blob); // href用于下载地址document.body.appendChild(a); //插到页面上a.click(); //通过点击触发URL.revokeObjectURL(a.href); //释放URL 对象document.body.removeChild(a); //删掉a标签} else {//IE10 + 下载navigator.msSaveBlob(blob, fileName);}
};
/*** * @param {*} res 接口返回的文件流*/
export const dowloadFileUrl = (res) => {console.log(res)const fileNames = res.headers['content-disposition']if (fileNames) {//解码const fileName = decodeURIComponent(fileNames.match(/=(.*)$/)[1])// 处理返回的文件流const content = res.dataconst blob = new Blob([content], {// type: res.data.type||"application/vnd.ms-excel",type: res.data.type||"application/octet-stream; charset=utf-8"});if ('download' in document.createElement('a')) {//非IE下载const a = document.createElement('a') //创建一个a标签a.download = fileName //指定文件名称a.style.display = 'none' //页面隐藏a.href = URL.createObjectURL(blob) // href用于下载地址document.body.appendChild(a) //插到页面上a.click() //通过点击触发URL.revokeObjectURL(a.href) //释放URL 对象document.body.removeChild(a) //删掉a标签} else {//IE10 + 下载navigator.msSaveBlob(blob, fileName)}}
}

总结:

直接拼接url为下载路径,创建一个a标签触发下载;

导出接口通过接口返回的二进制流,经过出来二进制流为Blob且type类型与接口一致。 

三、补充理论知识

MIME类型是什么:点击访问

MIME类型有哪些: 点击访问

常见MIME【媒体类型】 ,如下:

扩展名----------MIME类型

  .csv--------------text/csv

  .jpeg/.jpg-------image/jpeg

  .png-------------image/png

  .rar--------------application/x-rar-compressed

  .doc-------------application/msword

  .docx-----------application/vnd.openxmlformats-officedocument.wordprocessingml.document

  .xls--------------application/vnd.ms-excel

       .xlsx------------application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

  .zip--------------application/zip

相关文章:

下载文件,浏览器阻止不安全下载

背景: 在项目开发中,遇到需要下载文件的情况,文件类型可能是图片、excell表、pdf、zip等文件类型,但浏览器会阻止不安全的下载链接。 效果展示: 下载文件的两种方式: 一、根据接口的相对url,拼…...

基于javaweb的SpringBoot景区旅游管理系统设计和实现(源码+文档+部署讲解)

个人名片 🔥 源码获取 | 毕设定制| 商务合作:《个人名片》 ⛺️心若有所向往,何惧道阻且长 文章目录 个人名片运行环境技术栈适用功能说明使用说明 运行环境 Java≥8、MySQL≥5.7 1.运行环境:最好是java jdk 1.8,我们在这个平台…...

【17】Word:林楚楠-供应链❗

目录 题目 NO1.2 NO3 NO4 NO5 NO6 NO7 NO89 题目 NO1.2 另存为:文件→另存为→文档→文件名/考生文件夹F12/FnF12→文件名/考生文件夹 插入→分节符→文本框→输入文件→排版_居中对齐→间距/回车去掉文本框的边框→选中文本框→格式:形状轮廓…...

Transformer中基于惊喜的遗忘机制

在语言建模任务上,拥有 760M 参数的 Titans(MAC) 在 WikiText 上达到了 19.93 的困惑度,显著优于同等规模的 Transformer++(25.21) 和 Mamba2(22.94)。在常识推理任务上,Titans 在包括 PIQA、HellaSwag、WinoGrande 等 9 个基准测试中的平均准确率达到 52.51%,超过了现…...

从玩具到工业控制--51单片机的跨界传奇【3】

在科技的浩瀚宇宙中,51 单片机就像一颗独特的星辰,散发着神秘而迷人的光芒。对于无数电子爱好者而言,点亮 51 单片机上的第一颗 LED 灯,不仅仅是一次简单的操作,更像是开启了一扇通往新世界的大门。这小小的 LED 灯&am…...

基于机器学习的用户健康风险分类及预测分析

完整源码项目包获取→点击文章末尾名片! 背景描述 在这个日益注重健康与体能的时代,健身已成为许多人追求健康生活的重要组成部分。 本数据集包含若干健身房会员的详细信息,包括年龄、性别、体重、身高、心率、锻炼类型、身体脂肪比例等多项关…...

CF 641A.Little Artem and Grasshopper(Java实现)

题目分析 蚂蚱会在n个房间中根据既定房间规则向固定方向跳跃固定长度,试问是否能够跳出这个长度(即落点位置在0或n1) 思路分析 输入n就有n个房间,n套规则(固定方向和跳跃距离),蚂蚱到哪个房间就…...

5 分钟复刻你的声音,一键实现 GPT-Sovits 模型部署

想象一下,只需简单几步操作,就能生成逼真的语音效果,无论是为客户服务还是为游戏角色配音,都能轻松实现。GPT-Sovits 模型,其高效的语音生成能力为实现自然、流畅的语音交互提供了强有力的技术支持。本文将详细介绍如何…...

1.Spring AI 从入门到实践

​Spring AI 从入门到实践 1.什么是Spring AI 2.使用Spring Boot&Spring AI快速构建AI应用程序 3.ChatClient&Chat Model简化与AI模型的交互 4.Spring AI Prompt:与大模型进行有效沟通 5.结构化输出大模型响应 6.实战:AI聊天机器人 Ben技术站关注Java技术&#x…...

第23篇 基于ARM A9处理器用汇编语言实现中断<五>

Q:怎样修改HPS Timer 0定时器产生的中断周期? A:在上一期实验的基础上,可以修改按键中断服务程序,实现红色LED上的计数值递增的速率,主程序和其余代码文件不用修改。 实现以下功能:按下KEY0…...

攻防世界 unseping

开启场景 整体来说是创建了一个case类,然后可接受post传来的ctf的值,并对其进行base64解码以及反序列化。所以我们能控制ctf变量。 先看__wakeup方法,该方法使用waf方法对$arg中的内容进行了防护,过滤掉了| & ; 空格 / cat f…...

Python编程与在线医疗平台数据挖掘与数据应用交互性研究

一、引言 1.1 研究背景与意义 在互联网技术飞速发展的当下,在线医疗平台如雨后春笋般涌现,为人们的就医方式带来了重大变革。这些平台打破了传统医疗服务在时间和空间上的限制,使患者能够更加便捷地获取医疗资源。据相关报告显示,中国基于互联网的医疗保健行业已进入新的…...

浔川 AI 翻译已修复,可正常使用

浔川 AI 翻译已修复,可正常使用 亲爱的用户们: 大家好!经过技术团队的不懈努力,浔川 AI 翻译平台已完成修复,目前各项功能均已恢复正常,可流畅使用。在此,我们向一直以来关心和支持浔川 AI 翻译…...

apidoc thinkphp likeadmin 遇到解析报错

报错: [Semantical Error] The annotation "notes" in method app\adminapi\controller\article\ArticleCateController::lists() was never imported. Did you maybe forget to add a "use" statement for this annotation? 解决办法: config/apidoc…...

第22篇 基于ARM A9处理器用汇编语言实现中断<四>

Q:怎样编写ARM A9处理器汇编语言代码配置使用按键和定时器中断? A:本次实验同样为中断模式和监督模式都设置ARM A9堆栈指针,并使能中断,此外在主程序中调用子程序CONFIG_HPS_TIMER和CONFIG_KEYS分别对HPS Timer 0&…...

重回C语言之老兵重装上阵(六)枚举

1. 什么是枚举 (enum)? 枚举(enum)是 C 语言中的一种数据类型,用于定义一组具名的整数常量。它可以使代码更加可读,帮助程序员更容易理解程序中的常量值。通过枚举,程序员可以使用有意义的名称来代替数字&…...

STL-list类

list的介绍和使用 list的介绍 list的介绍list的介绍 list是双向循环链表 list的使用 构造 list(size_t n,const value_type& val value_type())构造的list中包含n个值为val的元素list()构造空listlis(const list& x)拷贝构造函数list(inputlerator first,inputlter…...

Hanlp的学习

参考&#xff1a;HanLP 自然语言处理使用总结-CSDN博客 参考&#xff1a;Sprint Boot 工程中HanLP配置相对路径&#xff0c;始终有问题的解决方案_springboot hanlp-CSDN博客 <!--hanlp 依赖--><dependency><groupId>com.hankcs</groupId><artifa…...

Excel中函数SIGN()的用法

Excel中函数SIGN的用法 1. 函数详细讲解1.1 函数解释1.2 使用格式1.3 参数定义1.4 要点 2. 实用演示示例2.1 函数需求2.2 公式编写 3. 注意事项4. 文档下载5. 其他文章6. 获取全部Excel练习素材快来试试吧&#x1f970; 函数练习素材&#x1f448;点击即可进行下载操作操作注意…...

如何将本地电脑上的文件夹设置为和服务器的共享文件夹

将本地电脑上的文件夹设为与服务器共享的文件夹&#xff0c;通常是在本地开启文件共享&#xff0c;并配置相应的权限&#xff0c;使服务器可以访问该文件夹。以下以 Windows 系统为例说明具体操作步骤&#xff1a; 一、在本地电脑上设置共享文件夹 选择文件夹 找到需要共享的文…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...