首頁 web前端 js教程 koa2實作檔案上傳下載步驟詳解

koa2實作檔案上傳下載步驟詳解

Apr 27, 2018 pm 05:22 PM
koa2 步驟

這次帶給大家koa2實作檔案上傳下載步驟詳解,koa2實作檔案上傳下載的注意事項有哪些,下面就是實戰案例,一起來看一下。

前言

上傳下載在 web 應用程式中還是比較常見的,無論是圖片或其他檔案等。在 Koa 中,有許多中間件可以幫助我們快速的實作功能。

文件上傳

在前端上傳文件,我們都是透過表單上傳,而上傳的文件,在伺服器端並不能像普通參數一樣透過ctx .request.body 取得。我們可以用 koa-body 中間件來處理檔案上傳,它可以將請求體拼到 ctx.request 中。

// app.js
const koa = require('koa');
const app = new koa();
const koaBody = require('koa-body');
app.use(koaBody({
  multipart: true,
  formidable: {
    maxFileSize: 200*1024*1024 // 设置上传文件大小最大限制,默认2M
  }
}));
app.listen(3001, ()=>{
  console.log('koa is listening in 3001');
})
登入後複製

使用中間件後,就可以在 ctx.request.body.files 中取得上傳的檔案內容。要注意的就是設定 maxFileSize,不然上傳檔案一超過預設限制就會報錯。

接收到檔案之後,我們需要把檔案儲存到目錄中,回傳一個 url 給前端。在node 中的流程為

  1. 建立可讀流const reader = fs.createReadStream(file.path)

  2. 建立可寫流const writer = fs.createWriteStream('upload/newpath.txt')

  3. #可讀流透過管道寫入可寫流reader.pipe(writer)

const router = require('koa-router')();
const fs = require('fs');
router.post('/upload', async (ctx){
 const file = ctx.request.body.files.file; // 获取上传文件
 const reader = fs.createReadStream(file.path); // 创建可读流
 const ext = file.name.split('.').pop(); // 获取上传文件扩展名
 const upStream = fs.createWriteStream(`upload/${Math.random().toString()}.${ext}`); // 创建可写流
 reader.pipe(upStream); // 可读流通过管道写入可写流
 return ctx.body = '上传成功';
})
登入後複製

此方法適用於上傳圖片、文字檔案、壓縮檔案等。

檔案下載

koa-send 是靜態檔案服務的中間件,可用來實作檔案下載功能。

const router = require('koa-router')();
const send = require('koa-send');
router.post('/download/:name', async (ctx){
 const name = ctx.params.name;
 const path = `upload/${name}`;
 ctx.attachment(path);
  await send(ctx, path);
})
登入後複製

在前端進行下載,有兩個方法: window.open 和表單提交。這裡使用簡單一點的 window.open 。

<button onclick="handleClick()">立即下载</button>
<script>
 const handleClick = () => {
 window.open('/download/1.png');
 }
</script>
登入後複製

這裡window.open 預設是開啟一個新的窗口,一閃然後關閉,給用戶的體驗並不好,可以加上第二個參數window.open('/download/1.png ', '_self'); ,這樣就會在目前視窗直接下載了。然而這樣是將 url 取代目前的頁面,則會觸發 beforeunload 等頁面事件,如果你的頁面監聽了該事件做一些操作的話,那就有影響了。那麼也可以使用一個隱藏的 iframe 視窗來達到相同的效果。

<button onclick="handleClick()">立即下载</button>
<iframe name="myIframe" style="display:none"></iframe>
<script>
 const handleClick = () => {
 window.open('/download/1.png', 'myIframe');
 }
</script>
登入後複製

批次下載

批次下載和單一下載也沒什麼區別嘛,就多執行幾次下載而已嘛。這樣也確實沒什麼問題。如果把這麼多檔案打包成一個壓縮包,再只下載這個壓縮包,是不是體驗起來就好一點了呢。

檔案打包

archiver 是一個在 Node.js 中能跨平台實作打包功能的模組,支援 zip 和 tar 格式。

const router = require('koa-router')();
const send = require('koa-send');
const archiver = require('archiver');
router.post('/downloadAll', async (ctx){
 // 将要打包的文件列表
 const list = [{name: '1.txt'},{name: '2.txt'}];
 const zipName = '1.zip';
 const zipStream = fs.createWriteStream(zipName);
  const zip = archiver('zip');
  zip.pipe(zipStream);
 for (let i = 0; i < list.length; i++) {
 // 添加单个文件到压缩包
 zip.append(fs.createReadStream(list[i].name), { name: list[i].name })
 }
 await zip.finalize();
 ctx.attachment(zipName);
 await send(ctx, zipName);
})
登入後複製

如果直接打包整個資料夾,則不需要去遍歷每個檔案append 到壓縮包裡

const zipStream = fs.createWriteStream('1.zip');
const zip = archiver('zip');
zip.pipe(zipStream);
// 添加整个文件夹到压缩包
zip.directory('upload/');
zip.finalize();
登入後複製

注意:打包整個資料夾,產生的壓縮包檔案不可存放到該資料夾下,否則會不斷的打包。

中文編碼問題

當檔案名稱含有中文的時候,可能會出現一些預想不到的情況。所以上傳時,含有中文的話我會對檔案名稱進行 encodeURI() 編碼進行儲存,下載的時候再進行 decodeURI() 解密。

ctx.attachment(decodeURI(path));
await send(ctx, path);
登入後複製

ctx.attachment 將 Content-Disposition 設定為 “附件” 以指示客戶端提示下載。透過解碼後的檔案名稱作為下載檔案的名字進行下載,這樣下載到本地,顯示的還是中文名稱。

然鵝,koa-send 的源碼中,會對檔案路徑進行decodeURIComponent() 解碼:

// koa-send
path = decode(path)
function decode (path) {
 try {
  return decodeURIComponent(path)
 } catch (err) {
  return -1
 }
}
登入後複製

這時解碼後去下載含中文的路徑,而我們伺服器中存放的是編碼後的路徑,自然就找不到對應的檔案了。

要想解決這個問題,那就別讓它去解碼。不想動 koa-send 原始碼的話,可使用另一個中間件 koa-sendfile 來取代它。

const router = require('koa-router')();
const sendfile = require('koa-sendfile');
router.post('/download/:name', async (ctx){
 const name = ctx.params.name;
 const path = `upload/${name}`;
 ctx.attachment(decodeURI(path));
  await sendfile(ctx, path);
})
登入後複製

我相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

vue axios請求攔截實作想法(附程式碼)

#vue2實作購物車與位址選配步驟詳解

vue.js樹形控制項使用詳解

#

以上是koa2實作檔案上傳下載步驟詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何在iPhone中使Google地圖成為預設地圖 如何在iPhone中使Google地圖成為預設地圖 Apr 17, 2024 pm 07:34 PM

iPhone上的預設地圖是Apple專有的地理位置供應商「地圖」。儘管地圖越來越好,但它在美國以外的地區運作不佳。與谷歌地圖相比,它沒有什麼可提供的。在本文中,我們討論了使用Google地圖成為iPhone上的預設地圖的可行性步驟。如何在iPhone中使Google地圖成為預設地圖將Google地圖設定為手機上的預設地圖應用程式比您想像的要容易。請依照以下步驟操作–先決條件步驟–您必須在手機上安裝Gmail。步驟1–開啟AppStore。步驟2–搜尋“Gmail”。步驟3–點選Gmail應用程式旁

升級微信最新版本的步驟(輕鬆掌握微信最新版本的升級方法) 升級微信最新版本的步驟(輕鬆掌握微信最新版本的升級方法) Jun 01, 2024 pm 10:24 PM

不斷推出新版本以提供更好的使用體驗,微信作為中國的社交媒體平台之一。升級微信至最新版本是非常重要的,家人和同事的聯繫、為了保持與朋友、及時了解最新動態。 1.了解最新版本的特性與改進了解最新版本的特性與改進非常重要,在升級微信之前。效能改進和錯誤修復,透過查看微信官方網站或應用程式商店中的更新說明、你可以了解新版本所帶來的各種新功能。 2.檢查目前微信版本我們需要檢查目前手機上已安裝的微信版本、在升級微信之前。點擊,打開微信應用“我”然後選擇,菜單“關於”在這裡你可以看到當前微信的版本號,。 3.打開應

此 Apple ID 尚未在 iTunes Store 中使用:修復 此 Apple ID 尚未在 iTunes Store 中使用:修復 Jun 10, 2024 pm 05:42 PM

使用AppleID登入iTunesStore時,可能會在螢幕上拋出此錯誤提示「此AppleID尚未在iTunesStore中使用」。沒有什麼可擔心的錯誤提示,您可以按照這些解決方案集進行修復。修正1–更改送貨地址此提示出現在iTunesStore中的主要原因是您的AppleID個人資料中沒有正確的地址。步驟1–首先,開啟iPhone上的iPhone設定。步驟2–AppleID應位於所有其他設定的頂部。所以,打開它。步驟3–在那裡,打開“付款和運輸”選項。步驟4–使用面容ID驗證您的存取權限。步驟

Shazam應用程式在iPhone中無法運作:修復 Shazam應用程式在iPhone中無法運作:修復 Jun 08, 2024 pm 12:36 PM

iPhone上的Shazam應用程式有問題? Shazam可協助您透過聆聽歌曲找到歌曲。但是,如果Shazam無法正常工作或無法識別歌曲,則必須手動對其進行故障排除。修復Shazam應用程式不會花費很長時間。因此,無需再浪費時間,請按照以下步驟解決Shazam應用程式的問題。修正1–禁用粗體文字功能iPhone上的粗體文字可能是Shazam無法正常運作的原因。步驟1–您只能從iPhone設定執行此操作。所以,打開它。步驟2–接下來,開啟其中的「顯示和亮度」設定。步驟3–如果您發現啟用了“粗體文本

如何關閉微信視訊號碼?微信視訊號關閉的詳細步驟 如何關閉微信視訊號碼?微信視訊號關閉的詳細步驟 Jan 02, 2024 pm 11:57 PM

要了解微信視訊號碼的關閉方法,首先需要知道微信這款聊天軟體的功能非常豐富。對於不同的人來說,微信視訊號碼有著不同的作用。對一般人而言,微信影片號碼只是分享個人拍攝的短影片的管道,可以將一些有趣的微信影片分享出去。而對於其他一些人來說,他們利用微信影片號碼來吸引流量。自然而然地,他們可能無法接受噴子和槓精的評論,因此想要關閉微信視頻號。接下來,本站小編將為大家介紹微信視頻號的關閉方法,有興趣的朋友們快來看看吧微信視頻號關閉操作步驟如下:我們首先打開微信,進入主頁面後,點擊底部的"我"按鈕,這將帶我們到一

Win11系統管理員權限取得步驟詳解 Win11系統管理員權限取得步驟詳解 Mar 08, 2024 pm 09:09 PM

Windows11作為微軟最新推出的作業系統,深受廣大用戶喜愛。在使用Windows11的過程中,有時候我們需要取得系統管理員權限,以便進行一些需要權限的操作。接下來將詳細介紹在Windows11中取得系統管理員權限的步驟。第一步,點擊“開始功能表”,在左下角可以看到Windows圖標,點擊該圖標即可開啟“開始功能表”。第二步,在「開始功能表」中尋找並點擊「

iPhone螢幕截圖不起作用:如何修復 iPhone螢幕截圖不起作用:如何修復 May 03, 2024 pm 09:16 PM

螢幕截圖功能在您的iPhone上不起作用嗎?截圖非常簡單,因為您只需同時按住「提高音量」按鈕和「電源」按鈕即可抓取手機螢幕。但是,還有其他方法可以在設備上捕獲幀。修復1–使用輔助觸控使用輔助觸控功能截取螢幕截圖。步驟1–轉到您的手機設定。步驟2–接下來,點選以開啟「輔助功能」設定。步驟3–開啟「觸摸」設定。步驟4–接下來,開啟「輔助觸控」設定。步驟5–打開手機上的「輔助觸控」。步驟6–打開“自訂頂級選單”以存取它。步驟7–現在,您只需將這些功能中的任何一個連結到螢幕擷取即可。因此,點擊那裡的首

iPhone中缺少時鐘應用程式:如何修復 iPhone中缺少時鐘應用程式:如何修復 May 03, 2024 pm 09:19 PM

您的手機中缺少時鐘應用程式嗎?日期和時間仍將顯示在iPhone的狀態列上。但是,如果沒有時鐘應用程序,您將無法使用世界時鐘、碼錶、鬧鐘等多項功能。因此,修復時鐘應用程式的缺失應該是您的待辦事項清單的首位。這些解決方案可以幫助您解決此問題。修復1–放置時鐘應用程式如果您錯誤地從主畫面中刪除了時鐘應用程序,您可以將時鐘應用程式放回原位。步驟1–解鎖iPhone並開始向左側滑動,直到到達「應用程式庫」頁面。步驟2–接下來,在搜尋框中搜尋「時鐘」。步驟3–當您在搜尋結果中看到下方的「時鐘」時,請按住它並

See all articles