下載文件,瀏覽器阻止不安全下載

背景:

在項目開發中,遇到需要下載文件的情況,文件類型可能是圖片、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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/66496.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/66496.shtml
英文地址,請注明出處:http://en.pswp.cn/web/66496.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

第15章:Python TDD應對貨幣類開發變化(二)

寫在前面 這本書是我們老板推薦過的,我在《價值心法》的推薦書單里也看到了它。用了一段時間 Cursor 軟件后,我突然思考,對于測試開發工程師來說,什么才更有價值呢?如何讓 AI 工具更好地輔助自己寫代碼,或許…

CSS 動畫相關屬性

定義和用法 一些 CSS 屬性可用于動畫制作,這意味著它們可用于過渡等效果中。 可設置動畫的屬性可以從一個值逐漸更改為另一個值,例如尺寸、數字、百分比和顏色。 瀏覽器支持 表格中的數字注明了完全支持 CSS 動畫的首個瀏覽器版本。 -webkit-、-moz…

SD/MMC驅動開發

一、介紹 MMC的全稱是”MultiMediaCard”――所以也通常被叫做”多媒體卡”,是一種小巧大容量的快閃存儲卡,特別應用于移動電話和數字影像及其他移動終端中。MMC存貯卡只有7pin,可以支持MMC和SPI兩種工作模式。 SD卡,數字安全記憶卡&#xf…

Elasticsearch:Jira 連接器教程第一部分

作者:來自 Elastic Gustavo Llermaly 將我們的 Jira 內容索引到 Elaasticsearch 中以創建統一的數據源并使用文檔級別安全性進行搜索。 在本文中,我們將回顧 Elastic Jira 原生連接器的一個用例。我們將使用一個模擬項目,其中一家銀行正在開發…

《探索煙霧目標檢測開源項目:技術與應用的深度剖析》

一、引言 在現代社會,火災猶如高懸的達摩克利斯之劍,時刻威脅著人們的生命財產安全。煙霧,作為火災發生的重要征兆,其及時、準確的檢測對于火災預防和控制起著舉足輕重的作用。煙霧目標檢測技術猶如敏銳的 “電子哨兵”&#xff…

Linux操作系統的靈魂,深度解析MMU內存管理

在計算機的奇妙世界里,我們每天使用的操作系統看似流暢自如地運行著各類程序,背后實則有著一位默默耕耘的 “幕后英雄”—— 內存管理單元(MMU)。它雖不常被大眾所熟知,卻掌控著計算機內存的關鍵命脈,是保障…

3.2 OpenAI 語言模型總覽:GPT 系列的演進與應用解析

OpenAI 語言模型總覽:GPT 系列的演進與應用解析 OpenAI 的語言模型,特別是 GPT(Generative Pre-trained Transformer)系列,代表了當前自然語言處理(NLP)技術的前沿。自從推出以來,這些模型不斷推進了文本生成、理解和交互的能力,成為了多個應用場景中的核心技術。本文…

【云嵐到家】-day02-客戶管理-認證授權

第二章 客戶管理 1.認證模塊 1.1 需求分析 1.基礎概念 一般情況有用戶交互的項目都有認證授權功能,首先我們要搞清楚兩個概念:認證和授權 認證: 就是校驗用戶的身份是否合法,常見的認證方式有賬號密碼登錄、手機驗證碼登錄等 授權:則是該用…

Thinkphp8 Apidoc 實際使用中遇到的問題解決

1. 接口去掉 Controller 問題: 正確的路徑應該是/api/login/register, 這塊controller有沒有地方配置的? 2. 自定義成功,錯誤消息有沒有辦法? 未完成, 待更新

2024春秋杯密碼題第一、二天WP

你是小哈斯? 題目內容: 年輕黑客小符參加CTF大賽,他發現這個小哈斯文件的內容存在高度規律性,并且文件名中有隱藏信息,他成功找到了隱藏的信息,并破解了挑戰。得意地說:“成功在于探索與質疑&#xff0c…

opencv對直方圖的計算和繪制

【歡迎關注編碼小哥,學習更多實用的編程方法和技巧】 1、直方圖的計算 cv::calcHist 是 OpenCV 中用于計算圖像直方圖的函數。它可以處理多通道圖像,并通過指定圖像、通道、掩膜、直方圖大小和范圍等參數來生成直方圖。 函數原型 void cv::calcHist(…

C++的auto_ptr智能指針:從誕生到被棄用的歷程

C作為一種功能強大的編程語言,為開發者提供了眾多便捷的特性和工具,其中智能指針是其重要特性之一。智能指針能夠自動管理內存,有效避免內存泄漏等常見問題。然而,并非所有智能指針都盡善盡美,auto_ptr便是其中的一個例…

游戲開發中常用的設計模式

目錄 前言一、工廠模式二、單例模式三、觀察者模式觀察者模式的優勢 四、狀態模式狀態模式的優勢 五、策略模式策略模式的優勢策略模式與狀態模式有什么區別呢? 六、組合模式七、命令模式八、裝飾器模式 前言 本文介紹了游戲開發中常用的設計模式,如工廠模式用于創…

C++并發編程之異常安全性增強

在并發編程中,異常安全是一個非常重要的方面,因為并發環境下的錯誤處理比單線程環境更加復雜。當多個線程同時執行時,異常不僅可能影響當前線程,還可能影響其他線程和整個程序的穩定性。以下是一些增強并發程序異常安全性的方法&a…

各語言鏡像配置匯總

鏡像配置匯總 Nodejs [ npm ]Python [ pip ] Nodejs [ npm ] // # 記錄日期:2025-01-20// 查詢當前使用的鏡像 npm get registry// 設置淘寶鏡像 npm config set registry https://registry.npmmirror.com/// 恢復為官方鏡像 npm config set registry https://regi…

Navicat Premium 數據可視化

工作區,數據源以及圖表 數據可視化是使用可視化組件(例如圖表,圖形和地圖)的信息和數據的圖形表示。 數據可視化工具提供了一種可訪問的方式,用于查看和理解數據中的趨勢,異常值和其他模式。 在Navicat中&…

linux通過web向mac遠程傳輸字符串,mac收到后在終端中直接打印。

要通過Web從Linux向Mac遠程傳輸字符串,并在Mac的終端中直接打印,可以使用以下方法。這里假設Linux作為服務器,Mac作為客戶端。 方法 1:使用Python的HTTP服務器 在Linux上啟動一個簡單的HTTP服務器,Mac通過curl獲取字符…

【系統分享01】Python+Vue電影推薦系統

大家好,作為一名老程序員,今天我將帶你一起走進電影推薦系統的世界,分享如何利用 Django REST Framework 和 Vue 搭建一套完整的電影推薦系統,結合 協同過濾算法,根據用戶評分與影片喜好,精準推送用戶可能喜…

Spring Boot+Vue

Spring BootVue 前后端分離是一種非常流行且高效的開發模式,以下是關于其相關方面的詳細介紹: 前端(Vue)部分 ? 項目搭建 ? 使用 Vue CLI 創建項目,它提供了豐富的插件和配置選項,能夠快速生成項目基礎…

第十四章:計算機新技術

文章目錄: 一:云計算 二:大數據 三:物聯網 四:人工智能 五:移動網絡與應用 六:電子商務 七:虛擬實現 八:區塊鏈 一:云計算 概念云基于?絡&#xff0…