2015-06-05 56 views
1

到目前爲止,我無法從JavaScript查詢Azure表。我按照https://msdn.microsoft.com/en-us/library/azure/dd179428.aspx的步驟描述瞭如何驗證請求,但到目前爲止,我只能得到一個Ajax錯誤回調。有人知道這裏出了什麼問題嗎?下面是我使用的代碼:嘗試從JavaScript中的Azure表存儲中獲取值時出錯

CORS代碼(C#控制檯應用程序):

using System; 
using System.Collections.Generic; 
using System.Windows.Forms; 

using Microsoft.WindowsAzure.Storage; 
using Microsoft.WindowsAzure.Storage.Table; 
using Microsoft.WindowsAzure.Storage.Shared.Protocol; 

namespace WindowsFormsApplication1 { 
    public partial class Form1 : Form { 

    private const String ACCOUNT_NAME = "<ACCOUNT_NAME>"; 
    private const String ACCOUNT_KEY = "<ACCOUNT_KEY>"; 

    public Form1() { 
     InitializeComponent(); 
    } 

    private CloudTableClient makeTableClient() { 
     String connectionString = "AccountName=" + ACCOUNT_NAME + ";AccountKey=" + ACCOUNT_KEY + ";DefaultEndpointsProtocol=https"; 
     CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString); 
     CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); 
     return tableClient; 
    } 

    private void btnAdd_Click(object sender, EventArgs e) { 
     addRule(makeTableClient()); 
    } 

    private void btnRemove_Click(object sender, EventArgs e) { 
     removeRule(makeTableClient()); 
    } 

    public void addRule(CloudTableClient tableClient) { 
     try { 
      CorsRule corsRule = new CorsRule() { 
       AllowedHeaders = new List<string> { "*" }, 
       AllowedMethods = CorsHttpMethods.Connect | CorsHttpMethods.Delete | CorsHttpMethods.Get | CorsHttpMethods.Head | CorsHttpMethods.Merge 
        | CorsHttpMethods.Options | CorsHttpMethods.Post | CorsHttpMethods.Put | CorsHttpMethods.Trace, 
       //Since we'll only be calling Query Tables, let's just allow GET verb 
       AllowedOrigins = new List<string> { "*" }, //This is the URL of our application. 
       ExposedHeaders = new List<string> { "*" }, 
       MaxAgeInSeconds = 1 * 60 * 60, //Let the browser cache it for an hour 
      }; 
      ServiceProperties serviceProperties = tableClient.GetServiceProperties(); 
      CorsProperties corsSettings = serviceProperties.Cors; 
      corsSettings.CorsRules.Add(corsRule); 
      tableClient.SetServiceProperties(serviceProperties); 
     } catch (Exception e) { 
      txtOutput.Text = e.ToString(); 
     } 
    } 

    public void removeRule(CloudTableClient tableClient) { 
     try { 
      ServiceProperties serviceProperties = tableClient.GetServiceProperties(); 
      CorsProperties corsSettings = serviceProperties.Cors; 
      corsSettings.CorsRules.RemoveAt(0); 
      tableClient.SetServiceProperties(serviceProperties); 
     } catch (Exception e) { 
      txtOutput.Text = e.ToString(); 
     } 
    } 
} 
} 

HTML/JavaScript代碼:

function CallTableStorage() { 
     var accountName = "<ACCOUNT_NAME>"; 
     var tableName = "<TABLE_NAME>"; 
     var userId = "<PARTITION_AND_ROW_KEY>"; 
     var secretKey = "<ACCOUNT_KEY>"; 

     var partitionKey = userId; 
     var rowKey = userId; 
     var queryString = encodeURIComponent(tableName + "(PartitionKey='" + partitionKey + "',RowKey='" + rowKey + "')"); 
     var urlPath = "https://" + accountName + ".table.core.windows.net/" + queryString + "?$select=adid"; 

     var VERB = "GET"; 
     var contentMD5 = ""; 
     var contentType = "text/plain; charset=UTF-8"; 
     var date = (new Date()).toUTCString(); 
     var canonicalizedResource = "/" + accountName + "/" + queryString; 

     stringToSign = VERB + "\n" + 
       contentMD5 + "\n" + 
       contentType + "\n" + 
       date + "\n" + 
       canonicalizedResource; 

     var signature = CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(CryptoJS.enc.Utf8.parse(stringToSign), CryptoJS.enc.Base64.parse(secretKey))); 

     $.ajax({ 
      url: urlPath, 
      type: 'GET', 
      success: function(data) { 
       console.log('Success:', data); 
      }, 
      beforeSend: function (xhr) { 
       xhr.setRequestHeader('x-ms-version', '2014-02-14'); 
       xhr.setRequestHeader('x-ms-date', date); 
       xhr.setRequestHeader('Authorization', "SharedKey " + accountName + ":" + signature); 
       xhr.setRequestHeader('Accept', 'application/json;odata=nometadata'); 
       xhr.setRequestHeader('Accept-Charset', 'UTF-8'); 
       xhr.setRequestHeader('DataServiceVersion', '3.0;NetFx'); 
       xhr.setRequestHeader('MaxDataServiceVersion', '3.0;NetFx'); 
       xhr.setRequestHeader("Access-Control-Allow-Origin", "*"); 
      }, 
      error: function(data) { 
       console.log('Error:', data); 
      } 
     }); 
    } 
    window.onload = CallTableStorage; 
+1

那麼錯誤說的是什麼? –

+0

哎呀!離開了。我編輯了一段代碼,將成功和錯誤回調函數輸出到控制檯以查看詳細信息。我還添加了一個缺失的行xhr.setRequestHeader(「Access-Control-Allow-Origin」,「*」);這顯然是需要的(根據我看到的錯誤)。目前,我看到的錯誤是:此站點使用SHA-1證書;建議您使用帶有比SHA-1更強大的哈希函數的簽名算法的證書。 – siddarfer

+0

我也從調試器中看到這一點:服務器無法驗證請求。確保授權標頭的值正確形成,包括簽名。這可能是真正的原因 - 我會繼續挖掘。 – siddarfer

回答

0

你可以嘗試從您的stringToSign和刪除內容類型看看是否有效?或者,如Michael Roberson所建議的那樣,爲Content-Type添加一個setRequestHeader並查看它是否有效。

另外,如果這個javascript/html是爲客戶端應用程序,你應該謹慎,因爲你的帳戶密鑰將以純文本形式發送。

相關問題