使用 JavaScript 将图像上传到Azure 存储 blob

使用静态 Web 应用通过具有 Azure 存储 SAS 令牌的 Azure 存储 @azure/storage-blob npm 包将文件上传到 Azure 存储 blob

先决条件

应用程序体系结构

此应用程序体系结构包括两个 Azure 资源:

  • 静态生成的客户端应用程序的 Azure 静态Web 应用。 该资源还提供托管的 Azure Functions API。 托管意味着静态Web 应用资源管理 API 资源供自己使用。
  • blob 存储的Azure 存储。

Diagram showing how a customer interacts from their computer to use the website to upload a file to Azure Storage directly.

步骤 说明
1 客户连接到静态生成的网站。 该网站托管在 Azure Static Web 应用中。
2 客户使用该网站选择要上传的文件。 在本教程中,前端框架为 Vite React ,上传的文件是图像文件。
3 该网站调用 Azure Functions API sas ,以基于要上传的文件的确切 文件名 获取 SAS 令牌。 无服务器 API 使用 Azure Blob 存储 SDK 创建 SAS 令牌。 API 返回用于上传文件的完整 URL,其中包括 SAS 令牌作为查询字符串。
https://YOUR-STORAGE-NAME.blob.core.windows.net/YOUR-CONTAINER/YOUR-FILE-NAME?YOUR-SAS-TOKEN
4 前端网站使用 SAS 令牌 URL 将文件直接上传到Azure Blob 存储

本地和生成环境

本教程使用以下环境:

  • 使用 GitHub Codespaces 或 Visual Studio Code 进行本地开发。
  • 使用 GitHub Actions 生成和部署。

1. 使用 GitHub 创建分支示例应用程序存储库

本教程使用 GitHub 操作将示例应用程序部署到 Azure。 需要 GitHub 帐户和示例应用程序存储库分支才能完成该部署。

  1. 在 Web 浏览器中,使用以下链接开始示例存储库的帐户分支: Azure-Samples/azure-typescript-e2e-apps
  2. 完成仅使用 分支创建示例分支的步骤。

2. 配置开发环境

提供开发容器环境,其中包含完成此项目中每个练习所需的所有依赖项。 可以在 GitHub Codespaces 中运行开发容器,也可以使用 Visual Studio Code 在本地运行。

GitHub Codespaces 运行由 GitHub 托管的开发容器,将 Visual Studio Code 网页版作为用户界面。 如需最直接的开发环境,请使用 GitHub Codespaces,它预安装了合适的开发人员工具和依赖项,用以完成本训练模块。

重要

所有 GitHub 帐户每月可以使用 Codespaces 最多 60 小时,其中包含 2 个核心实例。 有关详细信息,请参阅 GitHub Codespaces 每月包含的存储和核心小时数

  1. 在 Web 浏览器中,在示例存储库的 GitHub 分支上,选择 CODE 按钮,开始在分支分支上main创建新的 GitHub Codespace 的过程。

    GitHub screenshot of Code Spaces buttons for a repository.

  2. “Codespaces”选项卡上,选择省略号。 ...

    GitHub screenshot of Code Spaces tab with ellipsis control highlighted.

  3. 选择“ + 新建”,其中包含用于选择特定 Codespaces 开发容器的选项

    GitHub screenshot of Codespaces New with options menu item highlighted.

  4. 选择以下选项,然后选择“ 创建代码空间”。

    • 分公司: main
    • 开发容器配置: Tutorial: Upload file to storage with SAS Token
    • 区域:接受默认值
    • 计算机类型:接受默认值

    GitHub screenshot of Codespaces New with options menu with the following dev container highlighted, Tutorial: Upload file to storage with SAS Token.

  5. 等待 Codespace 启动。 此启动过程会花费几分钟时间。

  6. 在 codespace 中打开新终端。

    提示

    可以使用主菜单导航到“终端”菜单选项,然后选择“新建终端”选项。

    Screenshot of the codespaces menu option to open a new terminal.

  7. 检查你在本教程中使用的工具版本。

    node --version
    npm --version
    func --version
    

    本教程要求预安装在环境中的每个工具的以下版本:

    工具 版本
    Node.js ≥ 18
    npm ≥ 9.5
    Azure Functions Core Tools ≥ 4.5098
  8. 关闭终端。

  9. 本教程中的其余步骤在此开发容器的上下文中进行。

3.安装依赖项

本教程的示例应用位于 azure-upload-file-to-storage 文件夹中。 无需在项目中使用任何其他文件夹。

  1. 在 Visual Studio Code 中,打开终端并移动到项目文件夹。

    cd azure-upload-file-to-storage
    
  2. 拆分终端,使你有两个终端,一个用于客户端应用,一个用于 API 应用。

  3. 在某个终端中,运行以下命令以安装 API 应用的依赖项并运行应用。

    cd api && npm install
    
  4. 在其他终端中,运行命令以安装 客户端应用

    cd app && npm install
    

4. 使用 Visual Studio 扩展创建存储资源

创建要与示例应用一起使用的存储资源。 存储用于:

  • Azure Functions 应用中的触发器
  • Blob(文件)存储
  1. 导航到 Azure 存储扩展。

  2. 如有必要,请登录到 Azure。

  3. 右键单击该订阅,然后选择 Create Resource...

    Screenshot of Visual Studio Code in the Azure Explorer with the right-click menu showing the Create Resource item highlighted.

  4. 从列表中选择“创建存储帐户”。

  5. 使用下表按照提示进行操作,了解如何创建存储资源。

    属性 Value
    为新 Web 应用输入全局唯一名称。 为存储资源名称输入唯一值,例如fileuploadstor

    此唯一名称是在下一部分将使用的资源名称。 只使用字符和数字,长度不超过 24。 稍后将用到此帐户名称
    选择新资源的位置。 使用建议的位置。
  6. 应用创建过程完成后,将显示一条通知,其中包含有关新资源的信息。

    Screenshot of Visual Studio Code showing the Azure Activity Bar and the notification that the storage account was successfully created.

5. 配置 存储 CORS

由于浏览器用于上传文件,因此Azure 存储帐户需要配置 CORS 以允许跨域请求。

  1. 导航到 Azure 存储扩展。 右键单击存储资源,然后选择 “在门户中打开”。

  2. 在Azure 门户存储帐户设置部分中,选择“资源共享”(CORS)。

  3. 使用以下属性为本教程设置 CORS。

    • 允许的源: *
    • 允许的方法:除修补程序之外的所有方法
    • 允许的标头: *
    • 公开的标头: *
    • 最大年龄:86400

    这些设置用于本教程以简化步骤,并不打算指示最佳做法或安全性。 详细了解 CORS for Azure 存储

  4. 选择“保存”。

6. 授予对存储的匿名访问权限

创建受时间限制和权限限制的 SAS 令牌时,文件上传将受到客户端保护。 但是,上传文件后,在本教程方案中,你希望任何人看到该文件。 为此,需要更改可公开访问的存储权限。

即使该帐户可公开访问,但每个容器和每个 Blob 都可以具有专用访问权限。 对于本教程来说,更安全的方法过于复杂,即使用 SAS 令牌上传到一个存储帐户,然后将 Blob 移到具有公共访问权限的另一个存储帐户。

  1. 若要在Azure 门户中启用公共访问,请选择存储帐户的“概述”页,在“属性”部分中,选择“Blob 匿名访问”,然后选择“已禁用”。
  2. “配置 ”页上,启用 “允许 Blob 匿名访问”。

7. 创建上传容器

  1. 在Azure 门户存储帐户中,在“数据存储”部分中,选择“容器”。

  2. 选择 “+ 容器 ”以使用以下设置创建 upload 容器:

    • 名称:upload
    • 公共访问级别: Blob
  3. 选择创建

8.向自己授予 Blob 数据访问权限

创建资源时,无权查看容器的内容。 这是为特定的 IAM 角色保留的。 添加帐户,以便查看容器中的 Blob。

  1. 仍在Azure 门户存储帐户中,选择访问控制(IAM)。
  2. 选择“添加角色分配”。
  3. 搜索并选择存储 Blob 数据参与者。 选择下一步
  4. 选择 + 选择成员
  5. 搜索并选择你的帐户。
  6. 选择“查看 + 分配”。
  7. 选择“容器然后选择上传容器。 应该能够在没有授权错误的情况下看到容器中没有 Blob。

9.获取存储资源凭据

azure Functions API 应用中使用存储资源凭据连接到存储资源。

  1. 在Azure 门户中,在“安全性 + 网络”部分中,选择“访问密钥”。

  2. 请记住,API 文件位于 ./workspaces/azure-typescript-e2e-apps/azure-upload-file-to-storage/api.

  3. 在 API 文件夹中,将文件重命名local.settings.json.samplelocal.settings.json。 Git 忽略该文件,因此不会将其检查到源代码管理中。

  4. 更新使用下表的设置 local.settings.json

    属性 说明
    Azure_存储_AccountName Azure 存储帐户名称,例如: fileuploadstor 在源代码中用于连接到存储资源。
    Azure_存储_AccountKey Azure 存储帐户密钥 在源代码中用于连接到存储资源。
    AzureWebJobsStorage Azure 存储帐户连接字符串 Azure Functions 运行时用于存储状态和日志。

你似乎输入了同一帐户凭据两次,一次作为密钥,一次作为连接字符串。 你确实这样做了,但专门为了这个简单的教程。 一般来说,Azure Functions 应用应具有单独的存储资源,该资源不会用于其他目的。 在本教程稍后创建 Azure 函数资源时,无需为云资源设置 AzureWebJobs存储值。 只需设置源代码中使用的Azure_存储_AccountNameAzure_存储_AccountKey值。

10. 运行 API 应用

运行 Functions 应用,确保它在将它部署到 Azure 之前正常工作。

  1. 在 API 应用的终端中,运行以下命令以启动 API 应用。

    npm run start
    
  2. 等待 Azure Functions 应用启动。 你将收到一个通知,即 Azure Functions 应用的端口 7071 现已推出。 还应看到 API 应用的终端中列出的 API。

    Functions:
    
            list: [POST,GET] http://localhost:7071/api/list
    
            sas: [POST,GET] http://localhost:7071/api/sas
    
            status: [GET] http://localhost:7071/api/status
    
  3. 底部窗格中选择“端口 ”选项卡,然后右键单击 7071 端口,然后选择“ 端口可见性 ”,然后选择“ 公共”。

    如果未将此应用公开为公共应用,则使用客户端应用中的 API 时会出现错误。

  4. 若要测试 API 是否正常工作并连接到存储,请在底部窗格中的“端口”选项卡中,选择端口 7071 的“本地地址”区域中的地球图标。 这会打开函数应用的 Web 浏览器。

  5. 将 API 路由添加到 URL 地址栏: /api/sas?container=upload&file=test.png。 文件尚不在容器中是可以的。 API 根据要上传到的位置创建 SAS 令牌。

  6. JSON 响应应如下所示:

    {
        "url":"https://YOUR-STORAGE-RESOURCE.blob.core.windows.net/upload/test.png?sv=2023-01-03&spr=https&st=2023-07-26T22%3A15%3A59Z&se=2023-07-26T22%3A25%3A59Z&sr=b&sp=w&sig=j3Yc..."
    }
    
  7. 复制浏览器地址栏中的 API URL 的基(而不是 JSON 对象中的 SAS 令牌 URL),以在下一步中使用。 基 URL 是之前 /api/sas的所有内容。

11. 配置并运行客户端应用

  1. ./azure-upload-file-to-storage/app/.env.sample 文件重命名为 .env

  2. .env打开该文件,并将上一部分的基 URL 粘贴为值VITE_API_SERVER

    Codespaces 环境的示例可能类似于 VITE_API_SERVER=https://improved-space-fishstick-pgvxvxjpqgrh6qxp-7071.app.github.dev

  3. 在其他拆分终端中,使用以下命令启动客户端应用:

    npm run dev
    
  4. 等待终端返回以下通知,指出应用在端口 5173 上可用。

      VITE v4.4.4  ready in 410 ms
    
      ➜  Local:   https://localhost:5173/
      ➜  Network: use --host to expose
      ➜  press h to show help
    
  5. 选择底部窗格中的 “端口 ”选项卡,然后右键单击 5173 端口,然后选择地球图标。

  6. 应会看到简单的 Web 应用。

    Screenshot of web browser showing web app with Select File button available.

  7. 与 Web 应用交互:

    • 从本地计算机选择要上传的图像文件(*.jpg 或 *.png)。
    • 选择“获取 SAS”按钮,从 API 应用请求 SAS 令牌。 响应显示用于将文件上传到存储的完整 URL。
    • 选择“上传”按钮,将图像文件直接发送到存储。

    Screenshot of web browser showing web app with the image file uploaded and a thumbnail of the file displayed.

  8. 客户端应用和 API 应用在容器化开发人员环境中成功协同工作。

12. 提交代码更改

  1. 在 Visual Studio Code 中,打开“ 源代码管理 ”选项卡。
  2. 选择 + 图标以暂存所有更改。 这些更改应仅包含本教程的 app 包锁定.json 文件以及 api 文件夹。

13. 将静态 Web 应用部署到 Azure

Azure Functions 应用正在使用预览功能,它必须部署到 美国西部 2 才能正常运行。

  1. 在 Visual Studio Code 中,选择该 Azure 资源管理器。

  2. 在 Azure 资源管理器中,右键单击订阅名称,然后选择 Create Resource...

  3. 从列表中选择“ 创建静态 Web 应用 ”。

  4. 按照下表中的提示操作,了解如何创建静态 Web 应用资源。

    属性 Value
    为新 Web 应用输入全局唯一名称。 为存储资源名称输入唯一值,例如fileuploadstor

    此唯一名称是在下一部分将使用的资源名称。 只使用字符和数字,长度不超过 24。 稍后将用到此帐户名称
    选择新资源的位置。 使用建议的位置。
  5. 按照提示提供以下信息:

    Prompt Enter
    选择新资源的资源组。 使用为存储资源创建的资源组。
    输入新静态 Web 应用的名称 接受默认名称。
    选择 SKU 对于本教程,请选择免费 SKU。 如果订阅中已有免费的静态 Web 应用资源,请选择下一个定价层。
    选择生成预设以配置默认项目结构。 选择“自定义”。
    选择应用程序代码的位置 azure-upload-file-to-storage/app
    选择 Azure Functions 代码的位置 azure-upload-file-to-storage/api
    输入生成输出的路径... dist

    这是从应用到生成的静态文件的路径。
    选择新资源的位置。 选择附近的区域。
  6. 完成此过程后,将显示一个通知弹出窗口。 选择“查看/编辑工作流”

  7. 远程分支有一个新的工作流文件,用于部署到静态Web 应用。 在终端中使用以下命令将该文件拉取到环境:

    git pull origin main
    
  8. 打开位于 . 的 /.github/workflows/工作流文件。

  9. 验证特定于本教程静态 Web 应用的工作流部分应如下所示:

    ###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
    # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
    app_location: "/azure-upload-file-to-storage/app" # App source code path
    api_location: "/azure-upload-file-to-storage/api" # Api source code path - optional
    output_location: "dist" # Built app content directory - optional
    ###### End of Repository/Build Configurations ######
    
  10. 转到示例的 GitHub 分支, https://github.com/YOUR-ACCOUNT/azure-typescript-e2e-apps/actions 验证生成和部署操作(已命名 Azure Static Web Apps CI/CD、成功完成)。 完成此命令可能需要几分钟。

  11. 转到应用的Azure 门户并查看设置API 部分。 生产环境中的(managed)后端资源名称指示 API 已成功部署。

  12. 选择 (托管) 以查看应用中加载的 API 列表:

    • list
    • Sas
    • status
  13. 转到“概述”页,查找 已部署应用的 URL

  14. 应用的部署已完成。

14. 使用存储资源名称和密钥配置 API

在 API 正常工作之前,应用需要Azure 存储资源名称和密钥。

  1. 仍在 Azure 资源管理器中,右键单击静态 Web 应用资源,然后在门户中选择“打开”。

  2. “设置”部分选择“配置”。

  3. 使用下表添加应用程序设置。

    属性 说明
    Azure_存储_AccountName Azure 存储帐户名称,例如: fileuploadstor 在源代码中用于连接到存储资源。
    Azure_存储_AccountKey Azure 存储帐户密钥 在源代码中用于连接到存储资源。
  4. 在“配置”页上选择“ 保存 ”以保存这两个设置。

注意

无需设置客户端应用的 env 变量 VITE_API_标准版RVER,因为客户端应用和 API 托管在同一域中。

15. 使用 Azure 部署的静态 Web 应用

使用网站验证部署和配置是否成功。

  1. 在 Visual Studio Code 中,右键单击 Azure 资源管理器中的静态 Web 应用,然后选择“ 浏览站点”。
  2. 在新 Web 浏览器窗口中,选择“选择文件,然后选择要上传的图像文件(*.png 或 *.jpg)。
  3. 选择“ 获取 sas 令牌”。 此操作将文件名传递给 API,并接收上传文件所需的 SAS 令牌 URL。
  4. 选择“上传文件以使用 SAS 令牌 URL 上传文件。 浏览器显示上传文件的缩略图和 URL。

16. 清理资源

在 Visual Studio Code 中,使用资源组的 Azure 资源管理器,右键单击资源组,然后选择“ 删除”。

这会删除组中的所有资源,包括存储和静态 Web 应用资源。

疑难解答

下面记下了 GitHub 存储库中此示例的问题。 包括以下问题:

  • 文章的 URL
  • 有问题的文章中的步骤或上下文
  • 开发环境

示例代码

如果想继续探索此应用,可了解如何通过以下选择之一将应用部署到 Azure 进行托管: