Node.js Azure:使用Azure REST API删除表在按照文档执行时不起作用

Node.js Azure:使用Azure REST API删除表在按照文档执行时不起作用,node.js,azure,azure-storage,azure-table-storage,Node.js,Azure,Azure Storage,Azure Table Storage,我正在遵循表存储的Azure REST文档:。我只能在删除“Content-Length”标题后创建表,该标题被意外地标记为所需,并包含“x-ms-version”。这是我经过几次尝试和错误后可以实现的,因为它包含了标题 我面临的删除类似问题。严格按照文档操作时,我无法使用REST删除表。我尝试了一些尝试和错误,但它并没有帮助删除的情况 下面是创建和删除表的代码段 //Input your Storage Account and access-key associated to it. cons

我正在遵循表存储的Azure REST文档:。我只能在删除“Content-Length”标题后创建表,该标题被意外地标记为所需,并包含“x-ms-version”。这是我经过几次尝试和错误后可以实现的,因为它包含了标题

我面临的删除类似问题。严格按照文档操作时,我无法使用REST删除表。我尝试了一些尝试和错误,但它并没有帮助删除的情况

下面是创建和删除表的代码段

//Input your Storage Account and access-key associated to it.
const yourStorageAccountName = '';
const accessKeyStorageAccount = '';
const Client = require('node-rest-client').Client;
const crypto = require("crypto");

async function createTable() {
    let now = new Date();
    let nowUTC = now.toUTCString();
    let contentType = "application/json";
    // construct input value
    let stringToSign = `POST\n\n${contentType}\n${nowUTC}\n/${yourStorageAccountName}/Tables`;
    let accesskey = accessKeyStorageAccount;
    // create base64 encoded signature
    let key = new Buffer(accesskey, "base64");
    let hmac = crypto.createHmac("sha256", key);
    hmac.update(stringToSign);
    let sig = hmac.digest("base64");
    console.log("SIGNATURE : " + sig);
    let args = {
        headers: {
            "Authorization": "SharedKey " + yourStorageAccountName + ":" + sig,
            "Content-Type": contentType,
            "Accept": "application/json;odata=nometadata",
            "x-ms-version": "2015-12-11",
            "Date": nowUTC,
            "DataServiceVersion": '3.0',
            "MaxDataServiceVersion": '3.0'
        },
        data: {
            "TableName": "fortwo"
        }
    };
    let restClient = new Client();
    restClient.post(`https://${yourStorageAccountName}.table.core.windows.net/Tables`, args, function (data, response) {
        console.log(data);
        //console.log(response);
    });

}

async function deleteTable() {
    let now = new Date();
    let nowUTC = now.toUTCString();
    let contentType = "application/json"
    // construct input value
    let stringToSign = `DELETE\n\n${contentType}\n${nowUTC}\n/${yourStorageAccountName}/Tables(%27fourtwo%27)`;
    let accesskey = accessKeyStorageAccount;
    // create base64 encoded signature
    let key = new Buffer(accesskey, "base64");
    let hmac = crypto.createHmac("sha256", key);
    hmac.update(stringToSign);
    let sig = hmac.digest("base64");
    console.log("SIGNATURE : " + sig);
    console.log("nowutc : " + nowUTC);
    let args = {
        headers: {
            "Authorization": "SharedKey " + yourStorageAccountName + ":" + sig,
            "Content-Type": contentType,
            "Accept": "application/json;odata=nometadata",
            "Date": nowUTC,
            "x-ms-version": "2015-12-11",
            "DataServiceVersion": '3.0',
            "MaxDataServiceVersion": '3.0'
        }
    };
    let restClient = new Client();
    restClient.delete(`https://${yourStorageAccountName}.table.core.windows.net/Tables('fourtwo')`, args, function (data, response) {
        console.log(data);
        //console.log(response);
    });
}

async function getTableAcl() {
    let now = new Date();
    let nowUTC = now.toUTCString();
    let contentType = "application/json"
    // construct input value
    let stringToSign = `GET\n\n\n${nowUTC}\n/${yourStorageAccountName}/goodwa\ncomp:acl`;
    let accesskey = accessKeyStorageAccount;
    // create base64 encoded signature
    let key = new Buffer(accesskey, "base64");
    let hmac = crypto.createHmac("sha256", key);
    hmac.update(stringToSign);
    let sig = hmac.digest("base64");
    console.log("SIGNATURE : " + sig);
    console.log("nowutc : " + nowUTC);
    let args = {
        headers: {
            "Authorization": "SharedKey " + yourStorageAccountName + ":" + sig,
            "Date": nowUTC,
            "x-ms-version": "2015-12-11"
        }
    };
    let restClient = new Client();
    restClient.get(`https://${yourStorageAccountName}.table.core.windows.net/goodwa?comp=acl`, args, function (data, response) {
        console.log(JSON.stringify(data));
        //console.log(response);
    });
}


//createTable()
//deleteTable()
getTableAcl()
同样的行为也适用于儿童

我在这两个案子中都遗漏了什么吗? 我对create使用的变通方法没有意见。是否存在删除和删除的解决方法

通过Postman rest客户端在屏幕截图下方附加删除请求。


在上面的Rest调用中,我使用的是在代码片段中计算的签名。

除了一件小事之外,您的大部分代码都是正确的(很抱歉告诉您删除内容类型标题)。本质上,在
inputvalue
中,资源路径应该是url编码的。因此,您的
输入值应为:

let inputvalue = `DELETE\n\napplication/json\n${nowUTC}\n/${yourStorageAccountName}/Tables(%27mytab%27)`;
%27
转义
'
,即用
%27mytab%27
替换
'mytab'
,您不应该得到403错误

以下是我使用的代码:

function deleteTable() {
    let now = new Date();
    let nowUTC = now.toUTCString();
    // construct input value
    let inputvalue = `DELETE\n\napplication/json\n${nowUTC}\n/${yourStorageAccountName}/Tables(%27mytab%27)`;
    console.log('inputvalue');
    console.log(inputvalue)
    let accesskey = accessKeyStorageAccount;
    // create base64 encoded signature
    let key = new Buffer(accesskey, "base64");
    let hmac = crypto.createHmac("sha256", key);
    hmac.update(inputvalue);
    let sig = hmac.digest("base64");
    console.log("SIGNATURE : " + sig);
    let args = {
        headers: {
            "Authorization": "SharedKey " + yourStorageAccountName + ":" + sig,
            "Content-Type": "application/json",
            "Accept": "application/json;odata=nometadata",
            "x-ms-version": "2015-12-11",
            "x-ms-date": nowUTC,
            "DataServiceVersion": '3.0',
            "MaxDataServiceVersion": '3.0'
        }
    };
    let restClient = new Client();
    restClient.delete(`https://${yourStorageAccountName}.table.core.windows.net/Tables('mytab')`, args, function (data, response) {
        console.log(data);
        console.log(response.statusCode);
    });
}

您可以从header和inputValue中删除
内容类型
header,因为删除操作不需要它。接下来,请删除
Accept
标题。最后,请检查存储服务返回的错误消息。它将告诉您用于计算授权标头的字符串。您可以将其与inputValue进行比较。“他们两个应该完全匹配。”GauravMantri感谢您的回复。我试过你的建议,但没有用。在错误msg中,它没有像在文件/队列中一样,提到它用于计算末尾签名的字符串。我已经添加了一个标题组合的屏幕截图,正如您在问题描述中建议的那样,带有来自azure的错误消息。只是想补充一点,“内容类型”标题根据azure文档标记为所需。根据您的截图,URL中“mytab”周围有双引号。这些应该是单引号。谢谢分享截图。让我看看。但是,您不使用Azure存储的Node SDK而直接使用REST API有什么特别的原因吗?我很想知道这一点。@GauravMantri,是的,我们对使用REST有特殊要求。非常好的解决方案!代码在我这边起作用。还发现
内容类型
接受
标题是不必要的,除非我们使用值
2015-12-11
或更高版本指定
x-ms-version
,默认情况下,空内容被识别为atom提要,可以接受。因此,仅使用
授权
x-ms-date
标题也可能有效。@JerryLiu令人惊讶的是(即使删除的标题在azure文档中标记为必需),您的建议也有效。谢谢你提供的信息。@GauravMantri你的修复方法对我也有效。谢谢。@GauravMantri,对于表ACL上的GET操作,我得到403错误。这里的问题是,Azure表ACL文档中没有提到内容类型,但在授权头部分中,它被指定包含内容类型。因此,我在“stringToSign”中保持内容类型为空,在REST调用中不提供内容类型头。这个REST调用的代码在问题的代码片段中。你能让我知道我在这件事上有什么误解吗?你能把这作为一个新问题发表吗。请在问题中包含您正在使用的代码。403错误通常有3个原因:1)帐户密钥不正确2)客户端计算机上的时间设置不正确3)要签名的字符串不正确(使用REST API而不是SDK时)。