Azurite 開放原始碼模擬器提供免費的本機環境,用於測試雲端式應用程式。 當您對應用程式在本機運作方式感到滿意時,請切換至使用雲端中的 Azure 儲存體帳戶。
Azurite 是以 JavaScript 撰寫的輕量型儲存體模擬器,並在模擬 Azure 儲存體服務以進行本機開發的 Node.js 上執行。 它支援 Blob、佇列和資料表儲存體服務,並在 Windows、Linux 和 macOS 上提供跨平台支援。 如需安裝和執行 Azurite 的說明,請參閱 安裝並執行 Azurite 模擬器。
Azurite 還允許開發人員針對本地儲存環境運行測試,模擬 Azure 的行為,這對於整合和端到端測試至關重要。 若要深入瞭解如何使用 Azurite 進行自動化測試,請參閱 使用 Azurite 執行自動化測試。
Azurite 取代 Azure 儲存體模擬器,並持續更新以支援最新版本的 Azure 儲存體 API。
Azurite 和 Azure 儲存體之間的差異
Azurite 的本機執行個體與雲端中的 Azure 儲存體帳戶之間存在功能差異。
重要
Azurite 僅支援 Blob、佇列和資料表儲存體服務。 它不支援 Azure 檔案儲存體或 Azure Data Lake Storage Gen2,但在 Windows、Linux 和 macOS 上提供跨平臺支援。
端點和連線 URL
Azurite 的服務端點與 Azure 儲存體帳戶的端點不同。 本機電腦不會執行網域名稱解析,因此需要 Azurite 端點是本機位址。
當您在 Azure 儲存體帳戶中處理資源時,帳戶名稱是 URI 主機名稱的一部分。 要定址的資源是 URI 路徑的一部分:
<http|https>://<account-name>.<service-name>.core.windows.net/<resource-path>
下列 URI 是 Azure 儲存體帳戶中 Blob 的有效位址:
https://myaccount.blob.core.windows.net/mycontainer/myblob.txt
IP 樣式 URL
由於本機電腦不會解析網域名稱,因此帳戶名稱是 URI 路徑的一部分,而不是主機名稱。 對 Azurite 中的資源使用下列 URI 格式:
http://<local-machine-address>:<port>/<account-name>/<resource-path>
下列位址可用來存取 Azurite 中的 Blob:
http://127.0.0.1:10000/myaccount/mycontainer/myblob.txt
生產樣式 URL
或者,您可以修改主機檔案,以存取具有 生產樣式 URL 的帳戶。
首先,將一行或多行新增至主機檔案。 例如:
127.0.0.1 account1.blob.localhost
127.0.0.1 account1.queue.localhost
127.0.0.1 account1.table.localhost
接下來,設定環境變數以啟用自訂的儲存體帳戶和金鑰:
Code複製程式碼set AZURITE_ACCOUNTS="account1:key1:key2"
您可以新增更多帳戶。 請參閱連線到 Azurite 文章的自訂儲存體帳戶和金鑰一節。
啟動 Azurite 並使用自訂連接字串存取您的帳戶。 在下列範例中,連接字串會假設使用預設連接埠。
Code複製程式碼DefaultEndpointsProtocol=http;AccountName=account1;AccountKey=key1;BlobEndpoint=http://account1.blob.localhost:10000;QueueEndpoint=http://account1.queue.localhost:10001;TableEndpoint=http://account1.table.localhost:10002;
請勿使用 Azure 儲存體總管以這種方式存取預設帳戶。 儲存體總管一律會在 URL 路徑中新增帳戶名稱,導致失敗。
依預設,將 Azurite 搭配生產樣式 URL 使用時,帳戶名稱應該是完整網域名稱中的主機名稱,例如 http://devstoreaccount1.blob.localhost:10000/container。 若要在 URL 路徑 http://foo.bar.com:10000/devstoreaccount1/container中使用具有帳戶名稱的生產樣式 URL,例如 ,請務必在啟動 Azurite 時使用參數 --disableProductStyleUrl 。
如果您使用 host.docker.internal 作為要求 Uri 主機 (例如: http://host.docker.internal:10000/devstoreaccount1/container),Azurite 會從要求 Uri 路徑取得帳戶名稱。 無論您在啟動 Azurite 時是否使用參數 --disableProductStyleUrl ,此行為都是正確的。
調整和效能
Azurite 不支援大量連線的用戶端。 沒有效能保證。 Azurite 旨在用於開發和測試目的。
錯誤處理
Azurite 與 Azure 儲存體錯誤處理邏輯一致,但有差異。 例如,錯誤訊息可能不同,而錯誤狀態碼則一致。
RA-GRS
Azurite 支援讀取存取異地備援複寫 (RA-GRS)。 對於儲存資源,請附加 -secondary 至帳戶名稱來存取次要位置。 例如,下列位址可用來使用 Azurite 中的唯讀次要存取 Blob:
http://127.0.0.1:10000/devstoreaccount1-secondary/mycontainer/myblob.txt
表格支援
對 Azurite 中表格的支援目前處於預覽階段。 如需詳細資訊,請參閱 Azurite V3 表格 專案。
對持久函數的支援需要資料表。
重要
Azurite 對 Table Storage 的支援目前處於 預覽階段。 請參閱 Microsoft Azure 預覽版增補使用規定,以了解適用於 Azure 功能 (搶鮮版 (Beta)、預覽版,或尚未正式發行的版本) 的法律條款。
Azurite 是開源的
歡迎對 Azurite 做出貢獻和建議。 移至 Azurite GitHub 專案 頁面或 GitHub 問題 ,以取得我們正在追蹤即將推出的功能和錯誤修正的里程碑和工作專案。 詳細的工作專案也會在 GitHub 中追蹤。
工作區結構
初始化 Azurite 時,可能會在工作區位置中建立下列檔案和資料夾。
__blobstorage__– 包含 Azurite Blob 服務保存二進位資料的目錄__queuestorage__– 包含 Azurite 佇列服務保存二進位資料的目錄__tablestorage__– 包含 Azurite 資料表服務保存二進位資料的目錄__azurite_db_blob__.json– Azurite Blob 服務中繼資料檔案__azurite_db_blob_extent__.json– Azurite Blob 服務範圍中繼資料檔案__azurite_db_queue__.json– Azurite 佇列服務中繼資料檔案__azurite_db_queue_extent__.json– Azurite 佇列服務範圍 meta 資料檔__azurite_db_table__.json– Azurite 資料表服務中繼資料檔案__azurite_db_table_extent__.json– Azurite 表格服務範圍中繼資料檔案
若要清理 Azurite,請刪除檔案和資料夾並重新啟動模擬器。
後續步驟
- 安裝並執行 Azurite 模擬器說明 如何在本機電腦上安裝和執行 Azurite。
- 使用 SDK 和工具連線到 Azurite 說明如何使用各種 Azure 儲存體 SDK 和工具連線到 Azurite。
- 使用 Azure 儲存體模擬器進行開發和測試 ,記錄舊版 Azure 儲存體模擬器,並由 Azurite 取代。
在 React 中使用 Azure SDK 直接從瀏覽器安全地把附件上傳到 Blob
在 React 中直接從瀏覽器上傳檔案到 Azure Blob Storage,最常見且安全的方法是使用 SAS (Shared Access Signature) 權杖。這能避免在前端暴露你的帳戶金鑰,同時又能讓使用者直接將檔案傳給 Azure,減輕後端伺服器的負擔。
安全上傳流程
- 請求授權: React 前端向 Node.js 後端申請上傳權限。
- 核發 SAS 權杖: 後端驗證使用者身分後,向 Azure 申請一個限時(例如 5 分鐘)且限權限(只能寫入)的臨時網址。
- 直接上傳: React 拿到網址後,使用 Azure SDK 將檔案(Attachment)直接推送到 Blob Storage。
React 前端實作碼
首先需要安裝 SDK:npm install @azure/storage-blob
JavaScript
import { BlockBlobClient } from '@azure/storage-blob';
async function uploadFile(file) {
// 1. 向你的後端取得臨時的 SAS 網址 (這部分需實作 API)
const response = await fetch('/api/get-sas-url?fileName=' + file.name);
const { sasUrl } = await response.json();
// 2. 建立客戶端並執行上傳
const blobClient = new BlockBlobClient(sasUrl);
try {
await blobClient.uploadBrowserData(file, {
onProgress: (ev) => console.log(`上傳進度: ${ev.loadedBytes}`),
blobHTTPHeaders: { blobContentType: file.type }
});
alert('上傳成功!');
} catch (error) {
console.error('上傳失敗', error);
}
}
本地開發的注意事項
在本地端使用 Azurite 模擬器進行測試時,有兩個關鍵點需要設定:
- CORS 設定: 瀏覽器基於安全性會阻擋跨來源請求。你需要對 Azurite 執行命令來開啟 CORS,或是透過 Azure SDK 在後端初始化 Container 時,設定允許來自
http://localhost:5173(React 預設埠) 的存取。 - 連接字串: 誠如前面提到的,本地測試時 SAS 產生的網址會指向
http://127.0.0.1:10001。請確保你的 React 環境能存取到這個位置。
Azure SQL 與 Blob 的關聯
通常的做法是:檔案成功上傳到 Blob 後,你會拿到一個檔案路徑(URL)。接著,React 會再發一個請求給 Node.js,將這個 URL 與相關資訊(如上傳者、日期)存入 Azure SQL Database。這樣之後要讀取附件時,只需從 SQL 查出網址,前端就能直接顯示圖片或提供下載連結。
後端 Node.js 如何產生安全的 SAS 權杖程式碼
產生 SAS 權杖(Shared Access Signature)是保護雲端資源的核心技術。後端 Node.js 會扮演守門員的角色,利用帳戶金鑰運算出一串具備時效性的簽名,交給前端 React 使用。
Node.js 產生 SAS 權杖的程式碼
你需要安裝 @azure/storage-blob 套件。以下是一個簡單的 API 邏輯範例:
JavaScript
import {
BlobServiceClient,
StorageSharedKeyCredential,
generateBlobSASQueryParameters,
BlobSASPermissions
} from "@azure/storage-blob";
export async function getSasUrl(fileName) {
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const accountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY;
const containerName = "attachments";
const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);
// 設定權限:允許寫入 (Create/Write),且 5 分鐘後過期
const sasOptions = {
containerName,
blobName: fileName,
permissions: BlobSASPermissions.parse("cw"),
startsOn: new Date(),
expiresOn: new Date(new Date().valueOf() + 5 * 60 * 1000),
};
const sasToken = generateBlobSASQueryParameters(sasOptions, sharedKeyCredential).toString();
// 回傳完整的帶權杖網址給前端
return `https://${accountName}.blob.core.windows.net/${containerName}/${fileName}?${sasToken}`;
}
在本地端 Azurite 測試的調整
在本地使用 Azurite 模擬器時,因為連線協議是 HTTP 而非 HTTPS,且 AccountKey 是固定的測試金鑰,產生 SAS 的方式完全相同,但網址會變成 http://127.0.0.1:10001/...。
功能驗證與資料庫紀錄
當 React 拿到這個網址並成功上傳後,下一步通常是把檔案資訊寫入 Azure SQL。你會在 Node.js 中使用 mssql 套件來執行類似這樣的操作:
JavaScript
// 範例:將 Blob 網址存入 SQL Server
const request = new sql.Request();
await request.query(`
INSERT INTO Attachments (FileName, BlobUrl, UploadTime)
VALUES ('${fileName}', '${cleanUrl}', GETDATE())
`);
如何在 localhost 進行完整測試
- 啟動 Docker: 執行
docker-compose up啟動 Azurite 與 SQL Server。 - 建立 Container: 第一次執行時,你可以寫一個簡單的腳本確保 Azurite 裡已經建立名為
attachments的容器。 - 前端測試: 在 React 介面選取檔案,觀察瀏覽器的 Network 標籤。你應該會看到先發一個請求到 Node.js 拿 SAS 網址,接著 React 直接發一個 PUT 請求到
127.0.0.1:10001。 - 檢查結果: 使用 Azure Storage Explorer 查看 Azurite 是否多了檔案,並用 SQL 管理工具查看資料表是否多了紀錄。
檔案上傳後的預覽與權限管理,是提升使用者體驗與系統安全的重要環節。我們通常會根據檔案類型(如圖片或 PDF)來決定處理方式。
檔案預覽的處理方式
當檔案上傳到 Blob Storage 後,React 前端可以透過以下兩種方式展示預覽:
- 上傳前預覽 (Client-side): 在檔案還沒傳到雲端前,利用瀏覽器的
URL.createObjectURL(file)產生一個暫時的本地網址。這可以讓使用者立刻看到圖片,確認沒選錯檔案。 - 上傳後預覽 (Server-side): 當使用者下次回到頁面時,React 會從 Azure SQL 讀取檔案的網址。如果你的 Blob Container 設定為「私有」(Private),你就必須再次向後端請求一個「唯讀」的 SAS 權杖,前端才能顯示這張圖片。
下載權限管理
為了安全,我們通常不會將 Blob Container 設為公開。管理下載權限的標準做法如下:
- 動態產生下載連結: 當使用者點擊「下載」按鈕時,前端呼叫後端 API。後端確認該使用者有權限查看此附件後,產生一個有效期僅 1 分鐘的 SAS 權杖網址並回傳。
- 強制瀏覽器下載: 在產生 SAS 權杖時,後端可以設定
content-disposition參數。這樣當瀏覽器打開該網址時,會自動彈出「另存新檔」視窗,而不是直接在視窗中開啟檔案。
縮圖處理 (Thumbnail)
如果你的網頁需要一次顯示大量圖片預覽(例如相簿),直接讀取原圖會讓網頁變得很慢。專業的作法是利用 Azure Functions。當檔案一傳進 Blob Storage,會觸發一個自動程式,將圖片縮小並存到另一個名為 thumbnails 的容器中。React 則優先讀取縮圖,等使用者點擊後才載入原圖。
本地端測試預覽功能
在 localhost 測試時,Azurite 同樣支援這些行為。你可以試著在本地端產生一個過期時間只有 10 秒的 SAS 網址,然後在網頁上重新整理,觀察圖片是否在 10 秒後就因為權限失效而無法顯示。這能幫助你驗證系統的安全性是否符合預期。
這套流程串聯了 React 的前端互動、Node.js 的邏輯控制、以及 Azure 的儲存服務。你想了解如何在 Azure SQL 中設計這張附件資料表,好讓它能關聯到你的使用者或專案資料嗎?
除了 Azure Blob Storage,針對不同的應用場景,Azure 還提供幾種存放附件或檔案的替代方案。你可以根據檔案的大小、存取頻率以及是否需要被多台伺服器共享來選擇。
Azure Files (檔案分享)
這與 Blob Storage 的主要區別在於它支援標準的 SMB 與 NFS 協定。簡單來說,你可以把它想像成一個雲端網路硬碟(網路芳鄰)。
- 使用場景: 如果你的後端程式(Node.js)是跑在多個 Docker 容器或多台虛擬機上,且這些程式需要像存取本地磁碟一樣讀寫檔案,Azure Files 非常適合。
- 優點: 支援掛載為磁碟機,現有的程式碼不需要改寫成 SDK 調用,直接用檔案路徑就能讀寫。
Azure Data Lake Storage Gen2
這是在 Blob Storage 之上構建的專門用於大數據分析的服務。
- 使用場景: 如果你的附件不僅僅是拿來下載,之後還需要進行複雜的資料分析、機器學習,或是附件數量多達數百萬、數千萬等級。
- 優點: 擁有階層式命名空間(真正的資料夾結構),在處理大量檔案搬移或更名時,效能遠高於一般的 Blob。
資料庫直接存放 (不推薦但可行)
你可以將檔案轉成 Base64 字串或二進位格式(VARBINARY),直接存入 Azure SQL Database 的欄位中。
- 使用場景: 檔案極小(例如不到 100KB 的小圖示或簽名),且你希望備份資料庫時能連同檔案一起備份,不想管理兩套系統。
- 缺點: 會大幅增加資料庫的負擔與儲存成本,也會讓資料庫備份變得非常巨大且緩慢。通常我們還是建議「資料庫存路徑,Blob 存檔案」。
Azure App Service 內的磁碟空間
如果你的 Node.js 是部署在 Azure App Service,它本身也有一小塊磁碟空間(D 槽或 /home)。
- 使用場景: 極小規模的測試專案,或檔案只是暫存性質(例如上傳後處理完就刪除)。
- 風險: 當 App Service 重新啟動、更新或擴充(Scale out)時,這些檔案可能會消失。
該如何選擇?
| 需求場景 | 推薦方案 |
| 最通用、成本最低、React 直接上傳 | Azure Blob Storage |
| 多台伺服器掛載同一個網路硬碟 | Azure Files |
| 超大規模數據、需要資料夾權限管理 | Data Lake Gen2 |
| 檔案極小且不想分開管理 | Azure SQL (VARBINARY) |
在本地端驗證時,Azure Files 也有對應的 Docker 模擬器或可以用本地資料夾掛載(Volume)來模擬。你想了解如何把 Azure SQL 中的附件資料表與這些儲存路徑做關聯設計嗎?
在 Node.js 中操作 Azure SQL Server,最常用的套件是 mssql。這份範例會展示如何將上傳後的 Blob 資訊與業務邏輯(例如某個專案 ID)關聯起來,並儲存到資料庫中。
實作資料庫插入邏輯
這段程式碼展示了如何建立連線並使用參數化查詢(避免 SQL 注入攻擊)來新增紀錄。
JavaScript
import sql from 'mssql';
// 資料庫連線配置
const config = {
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
server: process.env.DB_SERVER,
database: process.env.DB_NAME,
options: {
encrypt: true, // 使用 Azure SQL 必須開啟加密
trustServerCertificate: true // 本地開發測試時可設為 true
}
};
async function saveAttachmentInfo(fileInfo) {
try {
let pool = await sql.connect(config);
await pool.request()
.input('TargetID', sql.Int, fileInfo.targetId)
.input('TargetType', sql.NVarChar, fileInfo.targetType)
.input('BlobName', sql.NVarChar, fileInfo.blobName)
.input('OriginalName', sql.NVarChar, fileInfo.originalName)
.input('FileSize', sql.BigInt, fileInfo.fileSize)
.input('ContentType', sql.NVarChar, fileInfo.contentType)
.query(`
INSERT INTO Attachments (TargetID, TargetType, BlobName, OriginalName, FileSize, ContentType, UploadTime)
VALUES (@TargetID, @TargetType, @BlobName, @OriginalName, @FileSize, @ContentType, GETDATE())
`);
console.log("附件資訊已存入 SQL Server");
} catch (err) {
console.error("資料庫寫入失敗", err);
}
}
關聯設計的實務細節
在資料庫中,你會發現 TargetID 與 TargetType 的設計非常靈活。舉例來說,如果一個附件是屬於「專案 A」,你的 TargetType 就存入 Project;如果附件是屬於「使用者 B」的證件照,則存入 User。這種設計能避免為每個功能都開一張附件表,方便統一管理所有檔案。
本地端測試技巧
在 localhost 使用 Docker 跑 SQL Server 容器時,有幾點要注意:
- 連線字串: 在
docker-compose.yaml中,Node.js 容器要連線的主機名稱是sqlserver(服務名稱)。但在你電腦上用 GUI 工具查看時,主機名稱是localhost。 - 資料表預建: 第一次啟動 Docker 容器時,資料庫是空的。你可以準備一個
init.sql腳本,透過 Docker 的掛載功能,讓容器啟動時自動建立好Attachments資料表。 - 資料持久化: 確保你有設定
volumes,這樣你在開發過程中重啟 Docker 容器,存進去的附件紀錄才不會消失。
完整的測試流程驗證
當你把這一整套串起來,測試流程會是:React 選檔 -> Node.js 給 SAS -> React 傳給 Azurite -> Node.js 寫入 SQL。你可以透過資料庫工具確認,每一筆 BlobName 欄位裡的路徑,是否都能在 Azurite 的儲存空間中找到對應的檔案。