介紹
我很難找到關於如何在基於 Expo 的行動應用程式中上傳和下載檔案的清晰範例。為了幫助面臨同樣挑戰的其他人或任何只是好奇的人,我寫了這篇文章。
在這個過程中,我們將探索有助於理解的關鍵概念:
- 緩衝區
- 意圖過濾器
- MIME 類型
- 應用程式/八位元位元組流
- 多部分/表單資料
- 還有更多...
我們將要涵蓋的內容:
- 使用 Fastify 伺服器傳送和接收檔案。
- 在 React Web 應用程式上傳、下載和顯示檔案。
- 在 React Native (Expo) 行動應用程式上傳、下載和顯示檔案。
所有程式碼和Postman集合都可以在我的GitHub上找到。
伺服器
伺服器在Fastify(Express.js 的現代化版本)上運作。要啟動應用程序,請執行以下操作:
- 使用終端導航到 /server
- 使用 npm install 安裝依賴項
- 使用 npm run dev 運行伺服器
在 app.js 中,我們有三個關鍵端點:
- 下載端點(/download)
fastify.get("/download", async function handler(_, reply) { const fd = await open(FILE_TO_DOWNLOAD); const stream = fd.createReadStream(); const mimeType = mime.lookup(FILE_TO_DOWNLOAD); console.log(`Downloading -> ${FILE_TO_DOWNLOAD}`); return reply .type(mimeType) .header( "Content-Disposition", `attachment; filename=${path.basename(FILE_TO_DOWNLOAD)}` ) .send(stream); });
此端點使用 createReadStream() 將 example.webp 傳送為流。包含 MIME 類型,以便用戶端知道如何處理該檔案。例如.webp,這將是image/webp。
?注意:MIME 類型定義了正在傳送的文件的格式。這有助於客戶端正確顯示它。
查看更多 MIME 類型。
Content-Disposition 標頭定義如何將內容呈現給客戶端。包括附件;文件名=;提示瀏覽器下載文件而不是內聯顯示它。若要直接顯示它,請使用內聯而不是附件。
了解更多有關內容處置的資訊
- 使用表單資料上傳多個檔案(/upload-multiples)
fastify.post("/upload-multiples", async function handler(request) { const parts = request.files(); const uploadResults = []; for await (const file of parts) { const fileBuffer = await file.toBuffer(); const filename = file.filename; const filePath = path.join(DIR_TO_UPLOAD, filename); await writeFile(filePath, fileBuffer); uploadResults.push({ filename, uploaded: true }); console.log(`Uploaded -> ${filePath}`); } return { uploadedFiles: uploadResults }; });
此端點接受多部分/表單資料請求。它:
- 從請求中檢索文件。
- 將每個檔案轉換為緩衝區(二進位資料的 JavaScript 表示)。
- 將檔案儲存到 /upload 目錄。
例如,請求可能如下所示:
- 使用八位元組流上傳檔案 (/upload-octet-stream)
fastify.get("/download", async function handler(_, reply) { const fd = await open(FILE_TO_DOWNLOAD); const stream = fd.createReadStream(); const mimeType = mime.lookup(FILE_TO_DOWNLOAD); console.log(`Downloading -> ${FILE_TO_DOWNLOAD}`); return reply .type(mimeType) .header( "Content-Disposition", `attachment; filename=${path.basename(FILE_TO_DOWNLOAD)}` ) .send(stream); });
此端點期望請求正文中有一個二進位檔案(應用程式/八位元組流)。與multipart/form-data不同的是,該檔案已經是二進位資料了,所以我們可以直接將其寫入磁碟。
請求在 Postman 中看起來像這樣:
網路(反應)
運行應用程式:
- 使用終端導航到 /web
- 使用 npm install 安裝依賴項
- 使用 npm run dev 啟動應用程式
Web 應用程式的所有功能都包含在 App.tsx 中:
這個 React 應用程式提供三個關鍵功能:
- 下載/顯示文件
fastify.post("/upload-multiples", async function handler(request) { const parts = request.files(); const uploadResults = []; for await (const file of parts) { const fileBuffer = await file.toBuffer(); const filename = file.filename; const filePath = path.join(DIR_TO_UPLOAD, filename); await writeFile(filePath, fileBuffer); uploadResults.push({ filename, uploaded: true }); console.log(`Uploaded -> ${filePath}`); } return { uploadedFiles: uploadResults }; });
當使用者點擊「下載」按鈕時,應用程式:
- 呼叫 /download 端點。
- 以二進位 blob 形式接收檔案。
- 從 blob 建立一個 objectURL,充當瀏覽器可以存取的臨時 URL。
行為取決於伺服器傳回的 Content-Disposition 標頭:
- 如果 Content-Disposition 包含內聯,則檔案將顯示在新選項卡中。
- 如果包含附件,則會自動下載該檔案。
為了觸發下載,應用程式會建立一個臨時的 ; href 設定為 objectURL 的元素並以程式設計方式點擊它,模擬使用者下載操作。
- 使用表單資料上傳文件
fastify.post("/upload-octet-stream", async function handler(request) { const filename = request.headers["x-file-name"] ?? "unknown.text"; const data = request.body; const filePath = path.join(DIR_TO_UPLOAD, filename); await writeFile(filePath, data); return { uploaded: true }; });
點選「上傳檔案」按鈕時:
- uploadFile 函數運行,建立一個隱藏的 元素並模擬使用者點擊。
- 一旦使用者選擇一個或多個文件,這些文件就會附加到 FormData 物件。
- 請求被傳送到 /upload-multiples 端點,該端點透過 multipart/form-data 接受檔案。
這使得伺服器能夠正確處理和保存上傳的檔案。
- 使用八位元組流上傳文件
const downloadFile = async () => { const response = await fetch(DOWNLOAD_API); if (!response.ok) throw new Error("Failed to download file"); const blob = await response.blob(); const contentDisposition = response.headers.get("Content-Disposition"); const isInline = contentDisposition?.split(";")[0] === "inline"; const filename = contentDisposition?.split("filename=")[1]; const url = window.URL.createObjectURL(blob); if (isInline) { window.open(url, "_blank"); } else { const a = document.createElement("a"); a.href = url; a.download = filename || "file.txt"; a.click(); } window.URL.revokeObjectURL(url); };
這種方法比使用 multipart/form-data 更簡單 - 只需將檔案作為二進位資料直接在請求正文中發送,並將檔案名稱包含在請求標頭中。
移動(世博會)
您可以使用以下命令啟動應用程式:
- 導航到終端中的移動目錄。
- 安裝依賴項:npm install
- 使用 npm run android 或 npm run ios 來執行項目
主要邏輯位於 App.tsx 中,它呈現以下內容:
fastify.get("/download", async function handler(_, reply) { const fd = await open(FILE_TO_DOWNLOAD); const stream = fd.createReadStream(); const mimeType = mime.lookup(FILE_TO_DOWNLOAD); console.log(`Downloading -> ${FILE_TO_DOWNLOAD}`); return reply .type(mimeType) .header( "Content-Disposition", `attachment; filename=${path.basename(FILE_TO_DOWNLOAD)}` ) .send(stream); });
要在新視圖中顯示檔案(就像瀏覽器在新分頁中開啟檔案一樣),我們必須將回應作為 blob 讀取,然後使用 FileReader 將其轉換為 base64。
我們將檔案寫入快取目錄(只有應用程式可以存取的私有目錄),然後使用 IntentLauncher 或共用(如果使用者使用 iOS)顯示它。
- 下載文件
fastify.post("/upload-multiples", async function handler(request) { const parts = request.files(); const uploadResults = []; for await (const file of parts) { const fileBuffer = await file.toBuffer(); const filename = file.filename; const filePath = path.join(DIR_TO_UPLOAD, filename); await writeFile(filePath, fileBuffer); uploadResults.push({ filename, uploaded: true }); console.log(`Uploaded -> ${filePath}`); } return { uploadedFiles: uploadResults }; });
這與 Web 進程類似,但我們必須使用 FileReader 將 blob 讀取為 base64,然後請求權限將檔案下載到使用者想要儲存檔案的位置。
- 使用表單資料上傳文件
fastify.post("/upload-octet-stream", async function handler(request) { const filename = request.headers["x-file-name"] ?? "unknown.text"; const data = request.body; const filePath = path.join(DIR_TO_UPLOAD, filename); await writeFile(filePath, data); return { uploaded: true }; });
使用 DocumentPicker 使用戶能夠選擇文件,然後使用 FormData 將所選文件附加到請求中。過程非常簡單。
- 將檔案上傳為八位元組流
const downloadFile = async () => { const response = await fetch(DOWNLOAD_API); if (!response.ok) throw new Error("Failed to download file"); const blob = await response.blob(); const contentDisposition = response.headers.get("Content-Disposition"); const isInline = contentDisposition?.split(";")[0] === "inline"; const filename = contentDisposition?.split("filename=")[1]; const url = window.URL.createObjectURL(blob); if (isInline) { window.open(url, "_blank"); } else { const a = document.createElement("a"); a.href = url; a.download = filename || "file.txt"; a.click(); } window.URL.revokeObjectURL(url); };
作為 Application/octet-stream 上傳比使用 FormData 更簡單:使用文件詳細資訊和內容類型設定標頭,然後將文件新增至請求正文,就是這樣!
結論
如何在平台之間查看、下載和上傳檔案可能有點令人困惑,在這篇文章中我們看到了最常見的。
希望對您有幫助?
讓我在@twitter上
以上是React & Expo - 如何上傳下載文件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript字符串替換方法詳解及常見問題解答 本文將探討兩種在JavaScript中替換字符串字符的方法:在JavaScript代碼內部替換和在網頁HTML內部替換。 在JavaScript代碼內部替換字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 該方法僅替換第一個匹配項。要替換所有匹配項,需使用正則表達式並添加全局標誌g: str = str.replace(/fi

本教程向您展示瞭如何將自定義的Google搜索API集成到您的博客或網站中,提供了比標準WordPress主題搜索功能更精緻的搜索體驗。 令人驚訝的是簡單!您將能夠將搜索限制為Y

因此,在這裡,您準備好了解所有稱為Ajax的東西。但是,到底是什麼? AJAX一詞是指用於創建動態,交互式Web內容的一系列寬鬆的技術。 Ajax一詞,最初由Jesse J創造

本文系列在2017年中期進行了最新信息和新示例。 在此JSON示例中,我們將研究如何使用JSON格式將簡單值存儲在文件中。 使用鍵值對符號,我們可以存儲任何類型的

利用輕鬆的網頁佈局:8 ESTISSEL插件jQuery大大簡化了網頁佈局。 本文重點介紹了簡化該過程的八個功能強大的JQuery插件,對於手動網站創建特別有用

核心要點 JavaScript 中的 this 通常指代“擁有”該方法的對象,但具體取決於函數的調用方式。 沒有當前對象時,this 指代全局對象。在 Web 瀏覽器中,它由 window 表示。 調用函數時,this 保持全局對象;但調用對象構造函數或其任何方法時,this 指代對象的實例。 可以使用 call()、apply() 和 bind() 等方法更改 this 的上下文。這些方法使用給定的 this 值和參數調用函數。 JavaScript 是一門優秀的編程語言。幾年前,這句話可

jQuery是一個很棒的JavaScript框架。但是,與任何圖書館一樣,有時有必要在引擎蓋下發現發生了什麼。也許是因為您正在追踪一個錯誤,或者只是對jQuery如何實現特定UI感到好奇

該帖子編寫了有用的作弊表,參考指南,快速食譜以及用於Android,BlackBerry和iPhone應用程序開發的代碼片段。 沒有開發人員應該沒有他們! 觸摸手勢參考指南(PDF)是Desig的寶貴資源


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Linux新版
SublimeText3 Linux最新版

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。