如何在Azure App Service部署的React应用中下载Azure Blob Storage大文件
解决Azure App Service部署的React项目访问Blob Storage下载大文件问题
一、App Service与Blob Storage的Azure AD关联步骤
给App Service启用系统托管标识:
- 进入Azure门户的目标App Service资源,打开「标识」选项卡,切换到「系统分配」标签,开启状态后保存,系统会自动生成对应的服务主体。
- 进入Blob Storage资源的「访问控制(IAM)」页面,添加角色分配:选择「存储Blob数据读取者」角色,成员类型选「托管标识」,再选中你的App Service对应的标识,完成权限分配。这样App Service就能通过自身托管标识访问Blob,无需硬编码密钥。
配置App Service环境变量:
在App Service的「配置」->「应用程序设置」中添加两个变量:AZURE_STORAGE_ACCOUNT_NAME:你的Blob存储账户名称AZURE_STORAGE_CONTAINER_NAME:目标文件所在的容器名称
二、App Service能否直接访问Blob文件?
可以直接访问,但不建议让前端通过App Service转发大文件——这会占用App Service的带宽和资源,更优方案是生成Blob的短期SAS令牌(用户委派SAS),让前端直接从Blob Storage下载,避免App Service成为性能瓶颈。
三、大文件下载实现流程
1. 后端中间层(Node.js/Express,用于安全生成SAS令牌)
先安装依赖:
npm install @azure/identity @azure/storage-blob
生成用户委派SAS令牌的代码示例:
const { DefaultAzureCredential } = require("@azure/identity"); const { BlobServiceClient, generateUserDelegationSAS } = require("@azure/storage-blob"); const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME; const containerName = process.env.AZURE_STORAGE_CONTAINER_NAME; async function getUserDelegationSAS(blobName) { const credential = new DefaultAzureCredential(); const blobServiceClient = new BlobServiceClient( `https://${accountName}.blob.core.windows.net`, credential ); // 获取用户委派密钥,最长有效期7天 const userDelegationKey = await blobServiceClient.getUserDelegationKey( new Date(), new Date(new Date().valueOf() + 7 * 24 * 60 * 60 * 1000) ); // 生成SAS令牌,仅授予读取权限,有效期1小时 const sasToken = generateUserDelegationSAS({ containerName, blobName, userDelegationKey, accountName, permissions: "r", startsOn: new Date(), expiresOn: new Date(new Date().valueOf() + 1 * 60 * 60 * 1000) }); return `https://${accountName}.blob.core.windows.net/${containerName}/${blobName}?${sasToken}`; } // 给前端暴露接口 app.get("/api/get-blob-sas/:blobName", async (req, res) => { try { const blobName = req.params.blobName; const downloadUrl = await getUserDelegationSAS(blobName); res.json({ downloadUrl }); } catch (error) { res.status(500).json({ error: error.message }); } });
2. React前端下载按钮实现
import { useState } from 'react'; const ExportButton = ({ blobName }) => { const [isDownloading, setIsDownloading] = useState(false); const handleDownload = async () => { setIsDownloading(true); try { // 调用后端接口获取带SAS的下载链接 const response = await fetch(`/api/get-blob-sas/${blobName}`); const data = await response.json(); // 创建a标签触发浏览器原生下载,大文件会自动分段处理 const a = document.createElement('a'); a.href = data.downloadUrl; a.download = blobName; document.body.appendChild(a); a.click(); document.body.removeChild(a); } catch (error) { alert('下载失败:' + error.message); } finally { setIsDownloading(false); } }; return ( <button onClick={handleDownload} disabled={isDownloading}> {isDownloading ? '导出中...' : '导出大文件'} </button> ); }; export default ExportButton;
四、关键注意事项
- 大文件优化:浏览器原生支持大文件分段下载,只要Blob通过SAS授权可访问,无需额外处理。
- 安全原则:禁止在前端直接使用Azure Identity SDK,避免权限泄露,通过后端生成短期SAS令牌更安全。
- 权限校验:确保App Service的托管标识已被分配「存储Blob数据读取者」角色,否则无法生成用户委派SAS。
内容的提问来源于stack exchange,提问作者Divakar R
相关产品推荐
相关产品推荐

