如何通过 Node.js 使用 Azure 表存储或 Azure Cosmos DB 表 APIHow to use Azure Table storage or the Azure Cosmos DB Table API from Node.js

提示

本文中的内容适用于 Azure 表存储和 Azure Cosmos DB 表 API。The content in this article applies to Azure Table storage and the Azure Cosmos DB Table API. Azure Cosmos DB 表 API 是表存储的高级产品,可提供吞吐量优化表、全局分发和自动辅助索引。The Azure Cosmos DB Table API is a premium offering for table storage that offers throughput-optimized tables, global distribution, and automatic secondary indexes.

本文介绍如何创建表、存储数据以及对数据执行 CRUD 操作。This article shows you how to create tables, store your data, and perform CRUD operations on the data. 选择 Azure 表服务或 Azure Cosmos DB 表 API。Choose either the Azure Table service or the Azure Cosmos DB Table API. 示例是采用 Node.js 编写的。The samples are written in Node.js.

创建 Azure 服务帐户Create an Azure service account

可以通过 Azure 表存储或 Azure Cosmos DB 使用表。You can work with tables using the Azure Table storage or the Azure Cosmos DB. 若要详细了解这两个服务中的表产品/服务之间的差异,请参阅表产品/服务一文。To learn more about the differences between table offerings in these two services, see the Table offerings article. 需要为所要使用的服务创建一个帐户。You'll need to create an account for the service you're going to use. 以下部分说明了如何创建 Azure 表存储和 Azure Cosmos DB 帐户,但你只需使用其中一个。The following sections show how to create both Azure Table storage and the Azure Cosmos DB account, however you can just use one of them.

创建 Azure 存储帐户Create an Azure storage account

创建 Azure 存储帐户的最简单方法是使用 Azure 门户The easiest way to create an Azure storage account is by using the Azure portal. 若要了解更多信息,请参阅 创建存储帐户To learn more, see Create a storage account.

也可以使用 Azure PowerShellAzure CLI 创建 Azure 存储帐户。You can also create an Azure storage account by using Azure PowerShell or Azure CLI.

如果暂时不想创建存储帐户,也可以使用 Azure 存储模拟器在本地环境中运行和测试代码。If you prefer not to create a storage account at this time, you can also use the Azure storage emulator to run and test your code in a local environment. 有关详细信息,请参阅使用 Azure 存储模拟器进行开发和测试For more information, see Use the Azure storage emulator for development and testing.

创建 Azure Cosmos DB 表 API 帐户Create an Azure Cosmos DB Table API account

有关创建 Azure Cosmos DB 表 API 帐户的说明,请参阅创建数据库帐户For instructions on creating an Azure Cosmos DB Table API account, see Create a database account.

配置应用程序以访问 Azure 存储或 Azure Cosmos DB 表APIConfigure your application to access Azure Storage or the Azure Cosmos DB Table API

若要使用 Azure 存储或 Azure Cosmos DB,需要适用于 Node.js 的 Microsoft Azure 存储 SDK,其中包括一组便于与存储 REST 服务进行通信的库。To use Azure Storage or Azure Cosmos DB, you need the Microsoft Azure Storage SDK for Node.js, which includes a set of convenience libraries that communicate with the Storage REST services.

使用 Node 包管理器 (NPM) 安装包Use Node Package Manager (NPM) to install the package

  1. 使用 PowerShell (Windows)、Terminal (Mac) 或 Bash (Unix) 等命令行接口导航到在其中创建了应用程序的文件夹。Use a command-line interface such as PowerShell (Windows), Terminal (Mac), or Bash (Unix), and navigate to the folder where you created your application.

  2. 在命令窗口中键入 npm install azure-storageType npm install azure-storage in the command window. 该命令的输出类似于以下示例。Output from the command is similar to the following example.

    azure-storage@0.5.0 node_modules\azure-storage
    +-- extend@1.2.1
    +-- xmlbuilder@0.4.3
    +-- mime@1.2.11
    +-- node-uuid@1.4.3
    +-- validator@3.22.2
    +-- underscore@1.4.4
    +-- readable-stream@1.0.33 (string_decoder@0.10.31, isarray@0.0.1, inherits@2.0.1, core-util-is@1.0.1)
    +-- xml2js@0.2.7 (sax@0.5.2)
    +-- request@2.57.0 (caseless@0.10.0, aws-sign2@0.5.0, forever-agent@0.6.1, stringstream@0.0.4, oauth-sign@0.8.0, tunnel-agent@0.4.1, isstream@0.1.2, json-stringify-safe@5.0.1, bl@0.9.4, combined-stream@1.0.5, qs@3.1.0, mime-types@2.0.14, form-data@0.2.0, http-signature@0.11.0, tough-cookie@2.0.0, hawk@2.3.1, har-validator@1.8.0)
    
  3. 可以手动运行 ls 命令,验证是否创建了 node_modules 文件夹 。You can manually run the ls command to verify that a node_modules folder was created. 在该文件夹中将找到 azure-storage 包,其中包含访问存储所需的库。Inside that folder you will find the azure-storage package, which contains the libraries you need to access storage.

导入包Import the package

将以下代码添加到应用程序中的 server.js 文件的顶部:Add the following code to the top of the server.js file in your application:

var azure = require('azure-storage');

添加连接字符串Add your connection string

可以连接到 Azure 存储帐户,也可以连接到 Azure Cosmos DB 表 API 帐户。You can either connect to the Azure storage account or the Azure Cosmos DB Table API account. 根据所使用的帐户类型获取连接字符串。Get the connection string based on the type of account you are using.

添加 Azure 存储连接Add an Azure Storage connection

Azure 模块读取环境变量 AZURE_STORAGE_ACCOUNT 和 AZURE_STORAGE_ACCESS_KEY 或 AZURE_STORAGE_CONNECTION_STRING 以获取连接到 Azure 存储器帐户所需的信息。The Azure module reads the environment variables AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_ACCESS_KEY, or AZURE_STORAGE_CONNECTION_STRING for information required to connect to your Azure Storage account. 如果未设置这些环境变量,则必须在调用 TableService 时指定帐户信息。If these environment variables are not set, you must specify the account information when calling TableService. 例如,以下代码创建 TableService 对象:For example, the following code creates a TableService object:

var tableSvc = azure.createTableService('myaccount', 'myaccesskey');

添加 Azure Cosmos DB 连接Add an Azure Cosmos DB connection

要添加 Azure Cosmos DB 连接,创建 TableService 对象并指定帐户名称、主键和终结点。To add an Azure Cosmos DB connection, create a TableService object and specify your account name, primary key, and endpoint. 可以从 Cosmos DB 帐户的 Azure 门户中的“设置” > “连接字符串”中复制这些值 。You can copy these values from Settings > Connection String in the Azure portal for your Cosmos DB account. 例如:For example:

var tableSvc = azure.createTableService('myaccount', 'myprimarykey', 'myendpoint');

创建表Create a table

下面的代码创建 TableService 对象并使用它来创建一个新表。The following code creates a TableService object and uses it to create a new table.

var tableSvc = azure.createTableService();

createTableIfNotExists 的调用将创建具有指定名称(如果该名称尚不存在)的一个新表。The call to createTableIfNotExists creates a new table with the specified name if it does not already exist. 下面的示例将创建一个名为“mytable”的新表(如果该表尚不存在):The following example creates a new table named 'mytable' if it does not already exist:

tableSvc.createTableIfNotExists('mytable', function(error, result, response){
  if(!error){
    // Table exists or created
  }
});

如果创建了新表,result.createdtrue,如果表已存在,则为 falseThe result.created is true if a new table is created, and false if the table already exists. response 包含有关该请求的信息。The response contains information about the request.

应用筛选器Apply filters

可以向使用 TableService 执行的操作应用可选筛选。You can apply optional filtering to operations performed using TableService. 筛选操作可包括日志记录、自动重试等。筛选器是实现具有签名的方法的对象:Filtering operations can include logging, automatic retries, etc. Filters are objects that implement a method with the signature:

function handle (requestOptions, next)

在对请求选项执行预处理后,该方法必须调用 next 并且传递具有以下签名的回调:After doing its preprocessing on the request options, the method must call next, passing a callback with the following signature:

function (returnObject, finalCallback, next)

在此回调中并且在处理 returnObject(来自对服务器请求的响应)后,回调必须调用 next(如果存在),继续处理其他筛选器,或者只调用 finalCallback,结束服务调用。In this callback, and after processing the returnObject (the response from the request to the server), the callback must either invoke next if it exists to continue processing other filters or simply invoke finalCallback otherwise to end the service invocation.

Azure SDK for Node.js 中附带了两个实现了重试逻辑的筛选器,分别是 ExponentialRetryPolicyFilter 和 LinearRetryPolicyFilter。以下代码创建使用 ExponentialRetryPolicyFilter 的 TableService 对象:Two filters that implement retry logic are included with the Azure SDK for Node.js, ExponentialRetryPolicyFilter** and LinearRetryPolicyFilter. The following creates a TableServiceobject that uses theExponentialRetryPolicyFilter`:

var retryOperations = new azure.ExponentialRetryPolicyFilter();
var tableSvc = azure.createTableService().withFilter(retryOperations);

将实体添加到表Add an entity to a table

若要添加实体,首先创建定义实体属性的对象。To add an entity, first create an object that defines your entity properties. 所有实体都必须都包含 PartitionKeyRowKey,它们是实体的唯一标识符。All entities must contain a PartitionKey and RowKey, which are unique identifiers for the entity.

  • PartitionKey - 确定实体存储在其中的分区。PartitionKey - Determines the partition in which the entity is stored.
  • RowKey - 唯一标识分区内的实体。RowKey - Uniquely identifies the entity within the partition.

PartitionKeyRowKey 都必须是字符串值。Both PartitionKey and RowKey must be string values. 有关详细信息,请参阅 Understanding the Table Service Data Model(了解表服务数据模型)。For more information, see Understanding the Table Service Data Model.

下面是如何定义实体的示例。The following is an example of defining an entity. dueDate 定义为一种 Edm.DateTime 类型。The dueDate is defined as a type of Edm.DateTime. 可以选择指定类型。如果未指定类型,系统会进行推断。Specifying the type is optional, and types are inferred if not specified.

var task = {
  PartitionKey: {'_':'hometasks'},
  RowKey: {'_': '1'},
  description: {'_':'take out the trash'},
  dueDate: {'_':new Date(2015, 6, 20), '$':'Edm.DateTime'}
};

备注

每个记录还有一个 Timestamp 字段,在插入或更新实体时,Azure 会设置该字段。There is also a Timestamp field for each record, which is set by Azure when an entity is inserted or updated.

还可以使用 entityGenerator 来创建实体。You can also use the entityGenerator to create entities. 下面的示例使用 entityGenerator 来创建相同的任务实体。The following example creates the same task entity using the entityGenerator.

var entGen = azure.TableUtilities.entityGenerator;
var task = {
  PartitionKey: entGen.String('hometasks'),
  RowKey: entGen.String('1'),
  description: entGen.String('take out the trash'),
  dueDate: entGen.DateTime(new Date(Date.UTC(2015, 6, 20))),
};

若要向表中添加实体,应将实体对象传递给 insertEntity 方法。To add an entity to your table, pass the entity object to the insertEntity method.

tableSvc.insertEntity('mytable',task, function (error, result, response) {
  if(!error){
    // Entity inserted
  }
});

如果操作成功,result 包含插入的记录的 ETag,而 response 包含有关操作的信息。If the operation is successful, result contains the ETag of the inserted record and response contains information about the operation.

示例响应:Example response:

{ '.metadata': { etag: 'W/"datetime\'2015-02-25T01%3A22%3A22.5Z\'"' } }

备注

默认情况下,insertEntity 不会在 response 信息中返回插入的实体。By default, insertEntity does not return the inserted entity as part of the response information. 如果计划对此实体执行其他操作,或者想要对信息进行缓存,则可在 result 中返回该实体。If you plan on performing other operations on this entity, or want to cache the information, it can be useful to have it returned as part of the result. 可以通过启用 echoContent 来执行此操作,如下所示:You can do this by enabling echoContent as follows:

tableSvc.insertEntity('mytable', task, {echoContent: true}, function (error, result, response) {...}

更新实体Update an entity

可使用多种方法来更新现有实体:There are multiple methods available to update an existing entity:

  • replaceEntity - 通过替换现有实体来更新现有实体。replaceEntity - Updates an existing entity by replacing it.
  • mergeEntity - 通过将新属性值合并到现有实体来更新现有实体。mergeEntity - Updates an existing entity by merging new property values into the existing entity.
  • insertOrReplaceEntity - 通过替换现有实体来更新现有实体。insertOrReplaceEntity - Updates an existing entity by replacing it. 如果不存在实体,将插入一个新实体。If no entity exists, a new one will be inserted.
  • insertOrMergeEntity - 通过将新属性值合并到现有实体来更新现有实体。insertOrMergeEntity - Updates an existing entity by merging new property values into the existing. 如果不存在实体,将插入一个新实体。If no entity exists, a new one will be inserted.

以下示例演示使用 replaceEntity 更新实体:The following example demonstrates updating an entity using replaceEntity:

tableSvc.replaceEntity('mytable', updatedTask, function(error, result, response){
  if(!error) {
    // Entity updated
  }
});

备注

默认情况下,更新某个实体时,不会查看要更新的数据是否曾被其他进程更新过。By default, updating an entity does not check to see if the data being updated has previously been modified by another process. 若要支持并发更新,请执行以下步骤:To support concurrent updates:

  1. 获取要更新的对象的 ETag。Get the ETag of the object being updated. 对于任何实体相关操作,该 ETag 会在 response 中返回,并且可通过 response['.metadata'].etag 检索。This is returned as part of the response for any entity-related operation and can be retrieved through response['.metadata'].etag.

  2. 对某个实体执行更新操作时,请以前检索的 ETag 信息添加到新的实体。When performing an update operation on an entity, add the ETag information previously retrieved to the new entity. 例如:For example:

    entity2['.metadata'].etag = currentEtag;entity2['.metadata'].etag = currentEtag;

  3. 执行更新操作。Perform the update operation. 如果实体在检索 ETag 值后已被修改,例如被应用程序的其他实例修改,则会返回一条 error,指出未满足请求中指定的更新条件。If the entity has been modified since you retrieved the ETag value, such as another instance of your application, an error is returned stating that the update condition specified in the request was not satisfied.

使用 replaceEntitymergeEntity 时,如果正在更新的实体不存在,则更新操作失败;因此,如果想要存储一个实体,而不管其是否已存在,请使用 insertOrReplaceEntityinsertOrMergeEntityWith replaceEntity and mergeEntity, if the entity that is being updated doesn't exist, then the update operation fails; therefore, if you want to store an entity regardless of whether it already exists, use insertOrReplaceEntity or insertOrMergeEntity.

如果更新操作成功,则 result 会包含所更新实体的 Etag。The result for successful update operations contains the Etag of the updated entity.

使用实体组Work with groups of entities

有时,有必要批量同时提交多项操作以确保通过服务器进行原子处理。Sometimes it makes sense to submit multiple operations together in a batch to ensure atomic processing by the server. 使用 TableBatch 类来创建一个批处理,并使用 TableServiceexecuteBatch 方法来执行批处理操作。To accomplish that, use the TableBatch class to create a batch, and then use the executeBatch method of TableService to perform the batched operations.

下面的示例演示了在一个批次中提交两个实体:The following example demonstrates submitting two entities in a batch:

var task1 = {
  PartitionKey: {'_':'hometasks'},
  RowKey: {'_': '1'},
  description: {'_':'Take out the trash'},
  dueDate: {'_':new Date(2015, 6, 20)}
};
var task2 = {
  PartitionKey: {'_':'hometasks'},
  RowKey: {'_': '2'},
  description: {'_':'Wash the dishes'},
  dueDate: {'_':new Date(2015, 6, 20)}
};

var batch = new azure.TableBatch();

batch.insertEntity(task1, {echoContent: true});
batch.insertEntity(task2, {echoContent: true});

tableSvc.executeBatch('mytable', batch, function (error, result, response) {
  if(!error) {
    // Batch completed
  }
});

如果批处理操作成功,则 result 包含批处理中每个操作的信息。For successful batch operations, result contains information for each operation in the batch.

使用批处理操作Work with batched operations

可以通过查看 operations 属性来检查添加到批处理中的操作。You can inspect operations added to a batch by viewing the operations property. 可以使用以下方法来处理操作:You can also use the following methods to work with operations:

  • clear - 清除批处理中的所有操作。clear - Clears all operations from a batch.
  • getOperations - 获取批处理的操作。getOperations - Gets an operation from the batch.
  • hasOperations - 如果批处理包含操作,则返回 true。hasOperations - Returns true if the batch contains operations.
  • removeOperations - 删除操作。removeOperations - Removes an operation.
  • size - 返回批处理中操作的数目。size - Returns the number of operations in the batch.

通过键检索实体Retrieve an entity by key

如果想要返回基于 PartitionKeyRowKey 的特定实体,请使用 retrieveEntity 方法。To return a specific entity based on the PartitionKey and RowKey, use the retrieveEntity method.

tableSvc.retrieveEntity('mytable', 'hometasks', '1', function(error, result, response){
  if(!error){
    // result contains the entity
  }
});

完成此操作后,result 包含该实体。After this operation is complete, result contains the entity.

查询实体集Query a set of entities

若要查询表,请使用 TableQuery 对象生成一个使用以下子句的查询:To query a table, use the TableQuery object to build up a query expression using the following clauses:

  • select - 要从查询返回的字段。select - The fields to be returned from the query.

  • where - where 子句。where - The where clause.

    • and - 一个 and where 条件。and - An and where condition.
    • or - 一个 or where 条件。or - An or where condition.
  • top - 要提取的项数。top - The number of items to fetch.

以下示例生成的查询返回 PartitionKey 为“hometasks”的前五项。The following example builds a query that returns the top five items with a PartitionKey of 'hometasks'.

var query = new azure.TableQuery()
  .top(5)
  .where('PartitionKey eq ?', 'hometasks');

由于未使用 select,因此将返回所有字段。Because select is not used, all fields are returned. 若要对表执行查询,请使用 queryEntitiesTo perform the query against a table, use queryEntities. 下面的示例使用此查询来返回“mytable”中的实体。The following example uses this query to return entities from 'mytable'.

tableSvc.queryEntities('mytable',query, null, function(error, result, response) {
  if(!error) {
    // query was successful
  }
});

如果成功,result.entries 会包含与查询匹配的一组实体。If successful, result.entries contains an array of entities that match the query. 如果查询无法返回所有实体,result.continuationToken 就不会是 NULL,因此可用作 queryEntities 的第三个参数来检索更多结果。If the query was unable to return all entities, result.continuationToken is non-null and can be used as the third parameter of queryEntities to retrieve more results. 对于初始查询,对第三个参数使用 null。For the initial query, use null for the third parameter.

查询一部分实体属性Query a subset of entity properties

对表的查询可以只检索实体中的少数几个字段。A query to a table can retrieve just a few fields from an entity. 这可以减少带宽并提高查询性能,尤其适用于大型实体。This reduces bandwidth and can improve query performance, especially for large entities. 使用 select 子句并传递要返回的字段的名称。Use the select clause and pass the names of the fields to return. 例如,下面的查询只返回 description 和 dueDate 字段 。For example, the following query returns only the description and dueDate fields.

var query = new azure.TableQuery()
  .select(['description', 'dueDate'])
  .top(5)
  .where('PartitionKey eq ?', 'hometasks');

删除实体Delete an entity

可以使用实体的分区键和行键删除实体。You can delete an entity using its partition and row keys. 在本例中,task1 对象包含要删除的实体的 RowKey 和 PartitionKey 值 。In this example, the task1 object contains the RowKey and PartitionKey values of the entity to delete. 然后,该对象被传递给 deleteEntity 方法。Then the object is passed to the deleteEntity method.

var task = {
  PartitionKey: {'_':'hometasks'},
  RowKey: {'_': '1'}
};

tableSvc.deleteEntity('mytable', task, function(error, response){
  if(!error) {
    // Entity deleted
  }
});

备注

考虑在删除项时使用 ETag,以确保项尚未被其他进程修改。Consider using ETags when deleting items, to ensure that the item hasn't been modified by another process. 请参阅更新实体了解如何使用 ETag。See Update an entity for information on using ETags.

删除表Delete a table

以下代码从存储帐户中删除一个表。The following code deletes a table from a storage account.

tableSvc.deleteTable('mytable', function(error, response){
    if(!error){
        // Table deleted
    }
});

如果不确定表是否存在,则使用 deleteTableIfExistsIf you are uncertain whether the table exists, use deleteTableIfExists.

使用继续标记Use continuation tokens

在所查询的表有大量的结果时,请查找继续标记。When you are querying tables for large amounts of results, look for continuation tokens. 如果在生成时不能识别何时存在继续标记,可能存在大量未意识到的数据可用于查询。There may be large amounts of data available for your query that you might not realize if you do not build to recognize when a continuation token is present.

查询实体在设置 continuationToken 属性(如果此类标记存在)期间,返回结果对象。The results object returned during querying entities sets a continuationToken property when such a token is present. 然后可以在执行查询时使用此对象,继续在分区和表实体之间移动。You can then use this when performing a query to continue to move across the partition and table entities.

在查询时,在查询对象实例和回调函数之间可能会提供 continuationToken 参数:When querying, you can provide a continuationToken parameter between the query object instance and the callback function:

var nextContinuationToken = null;
dc.table.queryEntities(tableName,
    query,
    nextContinuationToken,
    function (error, results) {
        if (error) throw error;

        // iterate through results.entries with results

        if (results.continuationToken) {
            nextContinuationToken = results.continuationToken;
        }

    });

如果检查 continuationToken 对象,就会发现 nextPartitionKeynextRowKeytargetLocation 等属性可用于循环访问所有结果。If you inspect the continuationToken object, you will find properties such as nextPartitionKey, nextRowKey and targetLocation, which can be used to iterate through all the results.

也可将 topcontinuationToken 配合使用,以便设置页面大小。You can also use top along with continuationToken to set the page size.

使用共享访问签名Work with shared access signatures

共享访问签名 (SAS) 是一种安全的方法,用于对表进行细致访问而无需提供存储帐户名或密钥。Shared access signatures (SAS) are a secure way to provide granular access to tables without providing your Storage account name or keys. 通常使用 SAS 来提供对数据的有限访问权限,例如允许移动应用查询记录。SAS are often used to provide limited access to your data, such as allowing a mobile app to query records.

受信任的应用程序(例如基于云的服务)可使用 TableServicegenerateSharedAccessSignature 生成 SAS,然后将其提供给不受信任的或不完全受信任的应用程序,例如移动应用。A trusted application such as a cloud-based service generates a SAS using the generateSharedAccessSignature of the TableService, and provides it to an untrusted or semi-trusted application such as a mobile app. 可使用策略生成 SAS,该策略描述了 SAS 的生效日期和失效日期,以及授予 SAS 持有者的访问级别。The SAS is generated using a policy, which describes the start and end dates during which the SAS is valid, as well as the access level granted to the SAS holder.

下面的示例生成了一个新的共享访问策略,该策略将允许 SAS 持有者查询 ('r') 表,在创建后 100 分钟过期。The following example generates a new shared access policy that will allow the SAS holder to query ('r') the table, and expires 100 minutes after the time it is created.

var startDate = new Date();
var expiryDate = new Date(startDate);
expiryDate.setMinutes(startDate.getMinutes() + 100);
startDate.setMinutes(startDate.getMinutes() - 100);

var sharedAccessPolicy = {
  AccessPolicy: {
    Permissions: azure.TableUtilities.SharedAccessPermissions.QUERY,
    Start: startDate,
    Expiry: expiryDate
  },
};

var tableSAS = tableSvc.generateSharedAccessSignature('mytable', sharedAccessPolicy);
var host = tableSvc.host;

请注意,还必须提供主机信息,因为 SAS 持有者尝试访问表时,必须提供该信息。Note that you must also provide the host information, as it is required when the SAS holder attempts to access the table.

然后,客户端应用程序将 SAS 用于 TableServiceWithSAS,以便针对表执行操作。The client application then uses the SAS with TableServiceWithSAS to perform operations against the table. 下面的示例连接到该表,并执行一个查询。The following example connects to the table and performs a query. 有关 tableSAS 的格式,请参阅使用共享访问签名 (SAS) 授予对 Azure 存储资源的有限访问权限一文。See Grant limited access to Azure Storage resources using shared access signatures (SAS) article for the format of tableSAS.

// Note in the following command, host is in the format: `https://<your_storage_account_name>.table.core.chinacloudapi.cn` and the tableSAS is in the format: `sv=2018-03-28&si=saspolicy&tn=mytable&sig=9aCzs76n0E7y5BpEi2GvsSv433BZa22leDOZXX%2BXXIU%3D`;

var sharedTableService = azure.createTableServiceWithSas(host, tableSAS);
var query = azure.TableQuery()
  .where('PartitionKey eq ?', 'hometasks');

sharedTableService.queryEntities(query, null, function(error, result, response) {
  if(!error) {
    // result contains the entities
  }
});

由于 SAS 在生成时只具有查询访问权限,因此如果尝试插入、更新或删除实体,则会返回错误。Because the SAS was generated with only query access, an error is returned if you attempt to insert, update, or delete entities.

访问控制列表Access Control Lists

还可以使用访问控制列表 (ACL) 为 SAS 设置访问策略。You can also use an Access Control List (ACL) to set the access policy for a SAS. 如果想要允许多个客户端访问某个表,但为每个客户端提供不同的访问策略,则访问控制列表会很有用。This is useful if you want to allow multiple clients to access the table, but provide different access policies for each client.

ACL 是使用一组访问策略实施的,每个策略都有一个关联的 ID。An ACL is implemented using an array of access policies, with an ID associated with each policy. 以下示例定义了两个策略,一个用于“user1”,一个用于“user2”:The following example defines two policies, one for 'user1' and one for 'user2':

var sharedAccessPolicy = {
  user1: {
    Permissions: azure.TableUtilities.SharedAccessPermissions.QUERY,
    Start: startDate,
    Expiry: expiryDate
  },
  user2: {
    Permissions: azure.TableUtilities.SharedAccessPermissions.ADD,
    Start: startDate,
    Expiry: expiryDate
  }
};

下面的示例获取 hometasks 表的当前 ACL,并使用 setTableAcl 添加新策略。The following example gets the current ACL for the hometasks table, and then adds the new policies using setTableAcl. 此方法具有以下用途:This approach allows:

var extend = require('extend');
tableSvc.getTableAcl('hometasks', function(error, result, response) {
if(!error){
    var newSignedIdentifiers = extend(true, result.signedIdentifiers, sharedAccessPolicy);
    tableSvc.setTableAcl('hometasks', newSignedIdentifiers, function(error, result, response){
      if(!error){
        // ACL set
      }
    });
  }
});

设置 ACL 后,可以根据某个策略的 ID 创建 SAS。After the ACL has been set, you can then create a SAS based on the ID for a policy. 以下示例为“user2”创建新的 SAS:The following example creates a new SAS for 'user2':

tableSAS = tableSvc.generateSharedAccessSignature('hometasks', { Id: 'user2' });

后续步骤Next steps

有关详细信息,请参阅以下资源。For more information, see the following resources.