你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
JavaScript 教程:使用 Azure Functions 和 Blob 存储上传和分析文件
在本教程中,你将了解如何将图像上传到 Azure Blob 存储并使用 Azure Functions、计算机视觉和 Cosmos DB 对其进行处理。 你还将了解如何在此过程中实现 Azure Function 触发器和绑定。 这些服务将一起分析包含文本的上传图像,从中提取文本,然后将文本存储在数据库行中,供以后分析或用于其他用途。
Azure Blob 存储是 Microsoft 针对云提供的可大规模缩放的对象存储解决方案。 Blob 存储设计用于存储图像和文档、流式处理媒体文件、管理备份和存档数据等等。 有关 Blob 存储的详细信息,请阅读概述页面。
警告
本教程旨在快速采用,因此它不遵循默认安全要求。 若要详细了解此方案并采用默认安全目标,请前往安全注意事项。
Azure Cosmos DB 是一种用于新式应用开发的完全托管的 NoSQL 数据库和关系数据库。
Azure Functions 是一种无服务器计算机解决方案,允许你编写和运行小块代码作为高度可缩放、无服务器、事件驱动的函数。 有关 Azure Functions 的详细信息,请阅读概述页面。
本教程介绍如何执行下列操作:
- 将图像和文件上传到 Blob 存储
- 使用 Azure Function 事件触发器处理上传到 Blob 存储的数据
- 使用 Azure AI 服务分析图像
- 使用 Azure Function 输出绑定将数据写入 Cosmos DB
先决条件
- 具有活动订阅的 Azure 帐户。 免费创建帐户。
- 已安装 Visual Studio Code。
- Azure Functions 扩展,用于部署和配置函数应用。
- Azure 存储扩展
- Azure 数据扩展插件
- Azure 资源扩展
创建存储帐户和容器
第一步是创建存储帐户来保存上传的 blob 数据,在本方案中为包含文本的图像。 存储帐户可提供多种不同的服务,但本教程仅使用了 Blob 存储。
在 Visual Studio Code 中,选择 Ctrl + Shift + P 以打开命令面板。
搜索“Azure 存储: 创建存储帐户(高级)”。
使用下表创建存储资源。
设置 值 名称 输入“msdocsstoragefunction”或类似内容。 资源组 创建你之前创建的 msdocs-storage-function
资源组。静态 Web 托管 否。 在 Visual Studio Code 中,选择 Shift + Alt + A 以打开 Azure 资源管理器。
展开“存储”部分,展开订阅节点并等待创建资源。
在 Visual Studio Code 中创建容器
- 仍在 Azure 资源浏览器中,找到新的存储资源,展开资源以查看节点。
- 右键单击“Blob 容器”,然后选择“创建 Blob 容器”。
- 输入名称
images
。 这将创建一个专用容器。
在 Azure 门户中从专用容器更改为公共容器
此过程需要一个公共容器。 若要更改该配置,请在 Azure 门户中进行更改。
- 右键单击 Azure 资源管理器中的存储资源,选择“在门户中打开”。
- 在“数据存储”部分,选择“容器”。
- 找到容器
images
,然后选择行尾的...
(省略号)。 - 选择“更改访问级别”。
- 选择“Blob (仅匿名读取访问 blob)”,然后选择“确定”。
- 返回到 Visual Studio Code。
在 Visual Studio Code 中检索连接字符串
- 在 Visual Studio Code 中,选择 Shift + Alt + A 以打开 Azure 资源管理器。
- 右键单击存储资源,然后选择“复制连接字符串”。
- 将该内容粘贴到某处供稍后使用。
- 记下存储帐户的名称
msdocsstoragefunction
供稍后使用。
创建 Azure AI 视觉服务
接下来,创建 Azure AI 视觉服务帐户来处理上传的文件。 视觉是 Azure AI 服务的一部分,可提供各种用于从图像中提取数据的功能。 有关 Azure AI 视觉的详细信息,请阅读概述页面。
在门户顶部的搜索栏中,搜索“计算机”并选择标有“计算机视觉”的结果。
在“计算机视觉”页面上,选择“+ 创建”。
在“创建计算机视觉”页面上,输入以下值:
- 订阅:选择所需的订阅。
- 资源组:使用之前创建的
msdocs-storage-function
资源组。 - 区域:选择离你最近的区域。
- 名称:输入名称
msdocscomputervision
。 - 定价层:如果可用,请选择“免费”,否则选择“标准 S1”。
- 选中“负责任的 AI 声明”框(如果同意这些条款)
选择底部的“查看 + 创建”。 Azure 需要花点时间来验证你输入的信息。 验证设置后,选择“创建”,Azure 将开始预配计算机视觉服务,这可能需要一些时间。
操作完成后,选择“转到资源”。
检索计算机视觉键
接下来,我们需要找到计算机视觉服务的密钥和终结点 URL,以在 Azure Function App 中使用。
在“计算机视觉”概述页面上,选择“密钥和终结点”。
在“键和终结点”页面上,复制“键 1”的值和“终结点”的值,并将它们粘贴到某处供稍后使用。 终结点的格式应为
https://YOUR-RESOURCE-NAME.cognitiveservices.azure.com/
创建 Cosmos DB 服务帐户
创建 Cosmos DB 服务帐户来存储文件分析结果。 Azure Cosmos DB 是一种用于新式应用开发的完全托管的 NoSQL 数据库和关系数据库。 你可以详细了解 Cosmos DB 及其针对多个不同行业数据库的支持 API。
虽然本教程在创建资源时指定了一个 API,但 Cosmos DB 的 Azure 函数绑定的配置方式与所有 Cosmos DB API 相同。
在门户顶部的搜索栏中,搜索“Azure Cosmos DB”并选择相应结果。
在“Azure Cosmos DB”页面上,选择“+ 创建”。 从 API 选项列表中选择“Azure Cosmos DB for NoSQL”。
在“创建 Cosmos DB”页面上,输入以下值:
- 订阅:选择所需的订阅。
- 资源组:使用之前创建的
msdocs-storage-function
资源组。 - 区域:选择你的资源组所在的同一区域。
- 名称:输入名称
msdocscosmosdb
。 - 定价层:如果可用,请选择“免费”,否则选择“标准 S1”。
选择底部的“查看 + 创建”。 Azure 会花点时间验证输入的信息。 验证设置后,选择“创建”,Azure 将开始预配计算机视觉服务,这可能需要一些时间。
操作完成后,选择“转到资源”。
依次选择“数据资源管理器”和“新建容器”。
使用以下设置创建新数据库和容器:
- 创建新数据库 ID:
StorageTutorial
。 - 输入新的容器 ID:
analysis
。 - 输入分区键:
/type
。
- 创建新数据库 ID:
保留其余默认设置,并选择“确定”。
获取 Cosmos DB 连接字符串
获取 Cosmos DB 服务帐户的连接字符串,以便在 Azure 函数应用中使用。
在“Cosmos DB”概述页面上,选择“键”。
在“键”页面上,复制主连接字符串以供稍后使用。
下载并配置示例项目
本教程中使用的 Azure 函数的代码可在此 GitHub 存储库的 JavaScript-v4
子目录中找到。 也可以使用以下命令克隆项目。
git clone https://github.com/Azure-Samples/msdocs-storage-bind-function-service.git \
cd msdocs-storage-bind-function-service/javascript-v4 \
code .
示例项目将完成以下任务:
- 检索环境变量以连接到存储帐户、计算机视觉和 Cosmos DB 服务
- 接受上传的文件作为 blob 参数
- 使用计算机视觉服务分析 blob
- 使用输出绑定将分析的图像文本作为 JSON 对象插入 Cosmos DB 中
下载并打开项目后,需要了解一些基本概念:
概念 | 目的 |
---|---|
函数 | Azure 函数由函数代码和绑定定义。 它们位于 ./src/functions/process-blobs.js 中。 |
触发器和绑定 | 触发器和绑定指示预期传入或传出函数的数据,以及要发送或接收该数据的服务。 |
本教程中使用的触发器和绑定无需编写代码即可连接到服务,可加快开发过程。
存储 Blob 输入触发器
下面的代码指定了在有 Blob 上传到图像容器时触发相应的函数。 该函数可在任何 Blob 名称(包括分层文件夹)上触发。
// ...preceding code removed for brevity
app.storageBlob('process-blob-image', {
path: 'images/{name}', // Storage container name: images, Blob name: {name}
connection: 'StorageConnection', // Storage account connection string
handler: async (blob, context) => {
// ... function code removed for brevity
- app.storageBlob - 存储 Blob 输入触发器用于将函数绑定到 Blob 存储中的上传事件。 触发器具有两个必需参数:
path
:触发器监视事件的路径。 该路径包括容器名称images
以及 blob 名称的变量替换。 此 blob 名称是从name
属性中检索的。{name}
:已上传的 blob 的名称。blob
的使用是传入函数的 blob 的参数名称。 请勿更改值blob
。connection
:存储帐户的连接字符串。 在本地开发时,值StorageConnection
与local.settings.json
文件中的名称相匹配。
Cosmos DB 输出触发器
完成相应函数后,该函数会将返回的对象作为数据插入到 Cosmos DB 中。
// ... function definition object
app.storageBlob('process-blob-image', {
// removed for brevity
// Data to insert into Cosmos DB
const id = uuidv4().toString();
const analysis = await analyzeImage(blobUrl);
// `type` is the partition key
const dataToInsertToDatabase = {
id,
type: 'image',
blobUrl,
blobSize: blob.length,
analysis,
trigger: context.triggerMetadata
}
return dataToInsertToDatabase;
}),
// Output binding for Cosmos DB
return: output.cosmosDB({
connection: 'CosmosDBConnection',
databaseName:'StorageTutorial',
containerName:'analysis'
})
});
对于本文中的容器,以下是必需的属性:
id
:Cosmos DB 创建新行所需的 ID。/type
:创建容器时指定的分区键。output.cosmosDB - Cosmos DB 输出触发器用于将函数的结果插入到 Cosmos DB 中。
connection
:存储帐户的连接字符串。 值StorageConnection
与local.settings.json
文件中的名称匹配。databaseName
:要连接到的 Cosmos DB 数据库。containerName
:写入函数返回的已分析图像文本值的表的名称。 该表必须已存在。
Azure 函数代码
下面是完整的函数代码。
const { app, input, output } = require('@azure/functions');
const { v4: uuidv4 } = require('uuid');
const { ApiKeyCredentials } = require('@azure/ms-rest-js');
const { ComputerVisionClient } = require('@azure/cognitiveservices-computervision');
const sleep = require('util').promisify(setTimeout);
const STATUS_SUCCEEDED = "succeeded";
const STATUS_FAILED = "failed"
const imageExtensions = ["jpg", "jpeg", "png", "bmp", "gif", "tiff"];
async function analyzeImage(url) {
try {
const computerVision_ResourceKey = process.env.ComputerVisionKey;
const computerVision_Endpoint = process.env.ComputerVisionEndPoint;
const computerVisionClient = new ComputerVisionClient(
new ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': computerVision_ResourceKey } }), computerVision_Endpoint);
const contents = await computerVisionClient.analyzeImage(url, {
visualFeatures: ['ImageType', 'Categories', 'Tags', 'Description', 'Objects', 'Adult', 'Faces']
});
return contents;
} catch (err) {
console.log(err);
}
}
app.storageBlob('process-blob-image', {
path: 'images/{name}',
connection: 'StorageConnection',
handler: async (blob, context) => {
context.log(`Storage blob 'process-blob-image' url:${context.triggerMetadata.uri}, size:${blob.length} bytes`);
const blobUrl = context.triggerMetadata.uri;
const extension = blobUrl.split('.').pop();
if(!blobUrl) {
// url is empty
return;
} else if (!extension || !imageExtensions.includes(extension.toLowerCase())){
// not processing file because it isn't a valid and accepted image extension
return;
} else {
//url is image
const id = uuidv4().toString();
const analysis = await analyzeImage(blobUrl);
// `type` is the partition key
const dataToInsertToDatabase = {
id,
type: 'image',
blobUrl,
blobSize: blob.length,
...analysis,
trigger: context.triggerMetadata
}
return dataToInsertToDatabase;
}
},
return: output.cosmosDB({
connection: 'CosmosDBConnection',
databaseName:'StorageTutorial',
containerName:'analysis'
})
});
此代码还从环境变量中检索基本配置值,例如 Blob 存储连接字符串和计算机视觉密钥。 这些环境变量在部署后添加到 Azure 函数环境。
默认函数还会使用名为 AnalyzeImage
的第二种方法。 此代码使用计算机视觉帐户的 URL 终结点和密钥向计算机视觉发出处理图像的请求。 该请求返回图像中发现的所有文本。 此文本将使用出站绑定写入 Cosmos DB。
配置本地设置
若要在本地运行项目,请在 ./local.settings.json
文件中输入环境变量。 使用之前在创建 Azure 资源时保存的值填充占位符值。
尽管 Azure 函数代码在本地运行,但它将连接到基于云的存储服务,而不是使用任何本地模拟器。
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "node",
"AzureWebJobsStorage": "",
"StorageConnection": "STORAGE-CONNECTION-STRING",
"StorageAccountName": "STORAGE-ACCOUNT-NAME",
"StorageContainerName": "STORAGE-CONTAINER-NAME",
"ComputerVisionKey": "COMPUTER-VISION-KEY",
"ComputerVisionEndPoint": "COMPUTER-VISION-ENDPOINT",
"CosmosDBConnection": "COSMOS-DB-CONNECTION-STRING"
}
}
创建 Azure Functions 应用
现在可以使用 Visual Studio Code 扩展将应用程序部署到 Azure。
在 Visual Studio Code 中,选择 Shift + Alt + A 以打开 Azure 资源管理器。
在“Functions”部分,找到并右键单击订阅,然后选择“在 Azure 中创建函数应用(高级)”。
使用下表创建函数资源。
设置 值 名称 输入 msdocsprocessimage 或类似内容。 运行时堆栈 选择一个 Node.js LTS 版本。 编程模型 选择“v4”。 OS 选择“Linux”。 资源组 选择之前创建的 msdocs-storage-function
资源组。位置 选择你的资源组所在的同一区域。 计划类型 选择“消耗”。 Azure 存储 选择前面创建的存储帐户。 Application Insights 暂时跳过。 Azure 将预配请求的资源,这需要一些时间才能完成。
部署 Azure Functions 应用
- 上一个资源创建过程完成后,在 Azure 资源管理器的“Functions”部分中右键单击新资源,然后选择“部署到函数应用”。
- 如果系统询问“是否确定要部署...”,请选择“部署”。
- 该过程完成后,会显示一条通知,其中包含“上传设置”的选项。 选择该选项。 这会将值从 local.settings.json 文件复制到 Azure 函数应用中。 如果通知在你进行选择之前就消失了,请继续执行下一部分。
为存储和计算机视觉添加应用设置
如果在通知中选择了“上传设置”,请跳过此部分。
Azure 函数已成功部署,但它还无法连接到存储帐户和计算机视觉服务。 必须先将正确的密钥和连接字符串添加到 Azure Functions 应用的配置设置。
在 Azure 资源管理器的“Functions”部分,查找你的资源,右键单击“应用程序设置”,然后选择“添加新设置”。
为以下机密输入新的应用设置。 将机密值从本地项目复制并粘贴到
local.settings.json
文件中。设置 StorageConnection StorageAccountName StorageContainerName ComputerVisionKey ComputerVisionEndPoint CosmosDBConnection
将 Azure Function 连接到不同服务所需的所有环境变量现已到位。
将图像上传到 Blob 存储
现在可以测试应用程序了! 你可以将 blob 上传到容器,然后验证图像中的文本是否已保存到 Cosmos DB。
- 在 Visual Studio Code 的 Azure 资源管理器中,在“存储”部分查找并展开你的存储资源。
- 展开“Blob 容器”,右键单击容器名称
images
,然后选择“上传文件”。 - 你可以在可下载示例项目的根目录的 images 文件夹中找到一些示例图像,也可以使用自己的图像。
- 对于“目标目录”,接受默认值
/
。 - 等待文件上传并列在容器中。
查看图片的文本分析
接下来,可以验证上传是否触发了 Azure 函数,以及图像中的文本是否已正确分析并保存到 Cosmos DB 中。
在 Visual Studio Code 中,在 Azure 资源管理器的 Azure Cosmos DB 节点下,选择资源,然后展开该资源以查找数据库“StorageTutorial”。
展开数据库节点。
分析容器现已应该可用。 选择容器的“文档”节点,以预览其中的数据。 你应会看到已上传文件的已处理图像文本的条目。
{ "id": "3cf7d6f0-a362-421e-9482-3020d7d1e689", "type": "image", "blobUrl": "https://msdocsstoragefunction.blob.core.windows.net/images/presentation.png", "blobSize": 1383614, "analysis": { ... details removed for brevity ... "categories": [], "adult": {}, "imageType": {}, "tags": [], "description": {}, "faces": [], "objects": [], "requestId": "eead3d60-9905-499c-99c5-23d084d9cac2", "metadata": {}, "modelVersion": "2021-05-01" }, "trigger": { "blobTrigger": "images/presentation.png", "uri": "https://msdocsstorageaccount.blob.core.windows.net/images/presentation.png", "properties": { "lastModified": "2023-07-07T15:32:38+00:00", "createdOn": "2023-07-07T15:32:38+00:00", "metadata": {}, ... removed for brevity ... "contentLength": 1383614, "contentType": "image/png", "accessTier": "Hot", "accessTierInferred": true, }, "metadata": {}, "name": "presentation.png" }, "_rid": "YN1FAKcZojEFAAAAAAAAAA==", "_self": "dbs/YN1FAA==/colls/YN1FAKcZojE=/docs/YN1FAKcZojEFAAAAAAAAAA==/", "_etag": "\"7d00f2d3-0000-0700-0000-64a830210000\"", "_attachments": "attachments/", "_ts": 1688743969 }
恭喜! 你已成功使用 Azure Functions 和计算机视觉处理上传到 Blob 存储的图像。
疑难解答
请使用下表帮助解决此过程中的问题。
问题 | 解决方法 |
---|---|
await computerVisionClient.read(url); 出现错误 Only absolute URLs are supported |
请确保 ComputerVisionEndPoint 终结点采用 https://YOUR-RESOURCE-NAME.cognitiveservices.azure.com/ 格式。 |
安全注意事项
作为初学者教程,此解决方案没有演示默认情况下的安全做法。 这是为了使你能够成功部署解决方案。 成功部署后的下一步是保护资源。 此解决方案使用三个 Azure 服务,每个服务都有自己的安全功能和安全默认配置注意事项:
- Azure Functions - 保护 Azure Functions
- Azure Storage - 有关 Blob 存储的安全性建议
- Azure 认知服务 -Azure AI 服务安全功能
代码示例
清理资源
如果不打算继续使用此应用程序,可以通过删除资源组来删除创建的资源。
- 从 Azure 资源管理器中选择“资源组”
- 从列表中找到并右键单击
msdocs-storage-function
资源组。 - 选择“删除”。 删除资源组的过程可能需要几分钟才能完成。