如何為你的應用程式加入檔案上傳:儲存、限制與安全性
要為你的應用程式加入檔案上傳,請把檔案存放在物件儲存空間(bucket)中,而不是伺服器的磁碟或資料庫裡;並在資料庫中儲存一筆小紀錄,包含檔案的金鑰、名稱、大小、類型與擁有者。在伺服器端檢查檔案大小與類型,並在開始之前就決定檔案是公開的(例如產品照片)還是私人的(例如發票)。私人檔案只有在確認請求者的身分後才能提供。在 AI 應用程式建置工具中,你可以用一段提示詞描述上傳功能;真正重要的是測試檔案在重新部署後仍然存在,而且不會被錯誤的人打開。
先決定你需要哪一種上傳
在建置之前,先回答三個問題:
- 什麼檔案? 個人大頭照、產品圖片、PDF、試算表、音訊、影片。這會決定類型與大小限制。
- 誰可以看到? 所有人(公開的圖庫),還是只有上傳者與管理員(合約、身分證件、客戶檔案)。
- 上傳之後會發生什麼? 只是儲存、顯示預覽、調整圖片大小,還是讀取其內容。
公開圖片與私人文件需要不同的設定,因此要先確定這一點。
檔案應該存放在哪裡
| 選項 | 運作方式 | 適合 | 注意事項 |
|---|---|---|---|
| 物件儲存空間(bucket) | 檔案存放在專門為此設計的服務中;你的資料庫儲存金鑰或 URL | 幾乎所有應用程式 | 必須正確設定存取規則 |
| 平台提供的儲存空間 | 你的應用程式建置工具或主機為你啟用一個 bucket | 在該平台上建置的應用程式 | 限制與價格跟隨平台 |
| 伺服器磁碟 | 檔案寫入應用程式伺服器的檔案系統 | 僅適用於本機開發 | 重新啟動或重新部署時經常被清空 |
| 資料庫中 | 把檔案的位元組存進資料表 | 幾乎從來不建議 | 會讓資料庫膨脹,拖慢備份 |
| 第三方上傳元件 | 由託管的上傳服務處理整個流程 | 大型媒體、圖片轉換 | 多一個廠商、帳號與帳單 |
對大多數應用程式來說,物件儲存空間加上資料庫紀錄,就是正確的答案。資料庫中的那一列是你的應用程式查詢的對象(「顯示這位使用者的文件」);bucket 只負責存放實際的位元組。
公開檔案與私人檔案
- 公開檔案(產品照片、部落格圖片、大頭照)可以透過公開 URL 提供。任何擁有連結的人都能開啟,對這類內容來說沒有問題。
- 私人檔案(發票、合約、醫療或身分文件、交付給客戶的成果)絕不能有可被猜到的公開 URL。伺服器會檢查已登入的使用者是否擁有該檔案或具有權限,然後要麼把檔案串流回傳,要麼回傳一個簽章 URL:一個只在短時間內有效的連結。
一個常見而且嚴重的錯誤,就是把私人檔案存在公開的 bucket 中,並使用可預測的檔名。任何人只要猜到 /uploads/invoice-102.pdf,就能拿到別人的發票。
提示詞範例
公開的圖片上傳:
讓管理員為每個產品上傳最多 5 張產品照片。接受 JPG、PNG 和 WebP,每張最大 5 MB。把檔案存到檔案儲存空間,並在 product_images 資料表中儲存每個檔案的金鑰、大小與順序,同時顯示縮圖與移除按鈕。在伺服器端驗證類型與大小,而不只是在瀏覽器端檢查。
私人文件上傳:
為已登入的客戶新增一個「文件」頁面。客戶可以上傳最大 20 MB 的 PDF。檔案是私人的:存到檔案儲存空間,並在 documents 資料表中儲存擁有者 ID、原始檔名、大小與上傳時間,只允許擁有者和管理員下載。下載必須經過伺服器路由,且該路由要檢查權限。絕不為這些檔案提供公開 URL。
後續可以加上的功能:
上傳時顯示進度條;如果檔案太大或類型錯誤,顯示清楚的錯誤訊息。
刪除文件紀錄時,同時刪除儲存的檔案。
逐步操作
- 為每個上傳欄位決定類型與大小限制。 要具體:「最大 20 MB 的 PDF」,而不是「文件」。
- 啟用儲存空間。 在 AI 建置工具中,直接要求上傳功能,它會幫你設定儲存空間;在其他平台上,建立一個 bucket,並把它的憑證存成伺服器端的機密。
- 為檔案紀錄建立資料表:ID、擁有者、儲存金鑰、原始名稱、類型、大小、建立時間。
- 在伺服器上建立上傳路由:檢查使用者是否已登入、檢查類型與大小、產生安全的儲存金鑰(而不是使用使用者的檔名)、儲存檔案、插入紀錄。
- 建立下載或顯示的路徑:公開檔案使用公開 URL;私人檔案則使用經過權限檢查的路由或簽章 URL。
- 建置 UI:檔案選擇器、必要時支援拖放、進度、預覽與錯誤訊息。
- 處理刪除,讓移除紀錄的同時也移除儲存的檔案。
- 測試:上傳、重新整理、重新部署或發布,然後確認檔案仍然可以載入。接著以另一位使用者登入,嘗試打開第一位使用者的私人檔案。
常見錯誤
- 把上傳寫到伺服器磁碟。 在開發環境中可以運作,但一重新啟動或重新部署,檔案就消失了。
- 相信瀏覽器端的檢查。 檔案輸入框的 accept 設定只是提示,不是安全機制。請在伺服器端檢查類型與大小。
- 使用使用者的檔名作為儲存金鑰。 名稱可能衝突,也可能包含奇怪的字元。請產生唯一的金鑰,並另外儲存原始名稱。
- 把私人檔案放在公開的 bucket 裡。 見上文;這正是會上新聞的那種錯誤。
- 允許任何檔案類型。 在某些設定中,從你的網域提供的 HTML 或 SVG 檔案可能會執行腳本。只接受你需要的類型。
- 沒有大小限制。 一次巨大的上傳可能耗盡你的儲存額度,或讓請求逾時。
- 孤立的檔案。 刪除了資料庫的列,卻沒有刪除檔案,會慢慢填滿你付費的儲存空間。
- 忘了手機。 手機照片可能很大,而且格式如 HEIC;要決定是接受還是轉換。
檢查清單
- 檔案存放在物件儲存空間,而不是伺服器磁碟或資料庫中
- 每個檔案都有一筆資料庫紀錄,包含擁有者、金鑰、名稱、類型與大小
- 在伺服器端檢查類型與大小
- 儲存金鑰是產生的,而不是取自檔名
- 私人檔案只有在通過權限檢查後才會提供
- 其他使用者即使拿到連結,也無法打開你的私人檔案
- 刪除紀錄時會一併刪除檔案
- 發布或重新部署之後,檔案仍能正常載入
- 上傳錯誤會清楚顯示,包括在手機上
Mythex 中的檔案上傳
當你的應用程式需要上傳時,Mythex 可以為專案自動啟用檔案儲存,因此你不必手動建立 bucket。你也可以在對話中輸入 /storage。它在免費方案與 Pro 方案都可以使用,免費方案的上限為 1 GB,你可以在設定 → 儲存空間中查看其狀態。
文件明確指出,已發布的主機不是持久的本機檔案系統,因此請要求代理程式使用平台儲存空間,而不是存到磁碟上。儲存的檔案與下載,會依大小與下載量從你的點數餘額扣除;Pro 方案的費率是免費方案的一半。參閱文件中的檔案儲存。
上傳功能通常會與資料庫(用於檔案紀錄)以及登入(用於私人檔案)搭配使用。如果你要打造一個讓客戶交換文件的地方,請參閱如何建置客戶入口網站,並在上線前完成安全檢查清單。
常見問題
上傳的檔案應該存放在哪裡?
存放在物件儲存空間(專門為檔案設計的服務,通常稱為 bucket),而不是應用程式伺服器的磁碟上,也不要放在資料庫裡。你的資料庫中只需要儲存檔案的金鑰或 URL,以及名稱、大小與擁有者等詳細資料。
為什麼我發布或重新部署後,上傳的檔案會消失?
大多數託管平台不會保留持久的本機磁碟:應用程式重新啟動或重新部署時,寫在它磁碟上的檔案就會遺失。請把上傳的檔案存到物件儲存空間。
如何讓上傳的檔案保持私密?
不要讓檔案可以被公開讀取。讓你的伺服器檢查已登入的使用者是否有權限查看該檔案,然後再把檔案傳送給他,或回傳一個短暫有效的簽章連結。
Mythex 支援檔案上傳嗎?
支援。當應用程式需要上傳功能時,Mythex 可以為專案啟用檔案儲存,免費方案與 Pro 方案都可以,免費方案的上限為 1 GB。你可以在對話中要求代理程式加入上傳功能,或輸入 /storage。