javascript Blob物件實現檔案下載
阿新 • • 發佈:2021-12-24
目錄
- 說明
- 一、Blob物件
- 二、前端
- 三、後端
- 總結
說明
最近遇到一個需求,檔案下載,但需要鑑權,這就意味著不能用後臺返回下載連結的方式進行下載,因為一旦被別人拿到這條連結,就可以不需要任何許可權就直接下載,因此需要換種思路,在一番百度之後,瞭解到了blob物件,這就是本文要講的內容
注意:本文僅為記錄學習軌跡,如有侵權,聯絡刪除
一、Blob物件
Blob 物件表示一個不可變、原始資料的類檔案物件。它的資料可以按文字或二進位制的格式進行讀取,也可以轉換成 ReadableStream 來用於資料操作。
二、前端
blob下載思路:
1) 使用ajax發起請求,指定接收型別為blob(responseType: ‘blob')
2)讀取請求返回的頭部資訊裡的content-disposition,返回的檔名就在這裡面(或者自定義檔名,可跳過此步驟)
3)使用URL.createObjectURL將請求的blob資料轉為可下載的url地址
4)使用a標籤下載
程式碼:
// 下載 export function download(query,newFileName) { return request({ url: '/file/download',method: 'get',responseType: 'blob',params: query }).then((res) => www.cppcns.com{ /** * blob下載思路 * 1) 使用ajax發起請求,指定接收型別為blob(responseType: 'blob') * 2)讀取請求返回的頭部資訊裡的content-disposition,返回的檔名就在這裡面(或者自定義檔名,可跳過此步驟) * 3)使用URL.createObjectURL將請求的blob資料轉為可下載的url地址 * 4)使用a標籤下載 * */ let blob = res.data // 從response的headers中獲取filename,後端responsewww.cppcns.com.setHeader("Content-disposition","attachment; filename=xxxx.docx") 設定的檔名; // let patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*') // let contentDisposition = decodeURI(res.headers['content-disposition']) // let result = patt.exec(contentDisposition) // let fileName = result[1] //將請求的blob資料轉為可下載的url地址 let url = URL.createObjectURL(blob) // 建立一個下載標籤<a> const aLink = document.createElement('a') aLink.href = url // 2.直接使用自定義檔名,設定下載檔名稱 aLink.setAttribute('download',newFileName ) document.body.appendChild(aLink) // 模擬點選下載 aLink.click() // 移除改下載標籤 document.body.removeChild(aLink); }) }
呼叫該方法
//下載 download(row) { // filePath:檔案路徑,例如:e:\upload\ // fileName:檔名, 例如:a.xlsx let form = { filePath: row.filePath,fileName: row.fileName,}; //下載,row.fileOriginalName是檔案的原始名稱,僅僅用於檔案下載時起個名字而已 download(form,row.fileOriginalName); } // 由於本人使用的是阿里的oss服務,所以只需要傳個檔案路徑回去後端,根據檔案路徑查詢oss介面得到返回的檔案流即可,例如(BufferedInputStream),在響應頭設定好返回的型別即可
三、後端
後端這裡用了阿里的oss服務,直接拿到檔案流(new BufferedInputStream(ossObject.getObjectContent())),如果是非oss的情況下,只需要讀取對應伺服器上面的檔案(File),轉成BufferedInputSt客棧ream後,直接套用下面的程式碼即可(即通過response.getOutputStream()設定BufferedOutputStream 就行了)
// response:響應
// filePath:檔案路徑,例如:e:\upload\
// fileName:檔名, 例如:a.xlsx
public void download(HttpServletResponse response,String filePath,String fileName) {
//待下載檔名
response.reset();
response.setHeader("Content-Disposition","attachment;filename=" + fileName);
response.setContentType("application/octet-stream");
response.setChVGUTNOtizaracterEncoding("utf-8");
// 建立OSSClient例項。
OSS ossClient = new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
// ossObject包含檔案所在的儲存空間名稱、檔名稱、檔案元資訊以及一個輸入流。
OSSObject ossObject = ossClient.getObject(bucketName,filePath + "/" + fileName);
BufferedInputStream in = null;
BufferedOutputStream out = null;
byte[] buff = new byte[1024];
int length = 0;
try {
in = new BufferedInputStream(ossObject.getObjectContent());
out = new BufferedOutputStream(response.getOutputStream());
while ((length = in.read(buff)) != -1){
out.write(buff,length);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(out != null){
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(in != null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ossClient != null) {
ossClient.shutdown();
}
}
}
總結
本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注我們的更多內容!