您好我正在尝试在THIS EXAMPLE之后开发一个文件上传机制到Azure blob存储,但我遇到了CORS的问题。 我已经设置了一个示例上传容器。 我还为blob存储启用了CORS(或者至少我认为这是因为以下代码没有给我任何错误):
var blobServiceProperties = AzureStorage.Default.BlobClient.GetServiceProperties();
ConfigureCors(blobServiceProperties);
AzureStorage.Default.BlobClient.SetServiceProperties(blobServiceProperties);
在上面的代码中,AzureStorage.Default.BlobClient对象是我的Blob Client的Lazy实例。 ConfigureCors方法定义如下:
private static void ConfigureCors(ServiceProperties serviceProperties)
{
serviceProperties.Cors = new CorsProperties();
serviceProperties.Cors.CorsRules.Add(new CorsRule()
{
AllowedHeaders = new List<string>() { "*" },
AllowedMethods = CorsHttpMethods.Put | CorsHttpMethods.Get | CorsHttpMethods.Head | CorsHttpMethods.Post | CorsHttpMethods.Delete,
AllowedOrigins = new List<string>() {
"https://localhost:444",
"https://xxx.yyy.com"
},
ExposedHeaders = new List<string>() { "*" },
MaxAgeInSeconds = 1800 // 30 minutes
});
}
哪个应该有效,因为我已经使用以下代码成功地为表服务设置了CORS:
var serviceProperties = AzureStorage.Default.TableClient.GetServiceProperties();
ConfigureCors(serviceProperties);
AzureStorage.Default.TableClient.SetServiceProperties(serviceProperties);
我正在使用Azure REST API在没有问题的情况下对Table Service执行操作。 我还调试了C#代码的执行,同时将CORS属性和URL正确指向云上的Azure服务(而不是开发存储)。 我的第一个问题是:
当我尝试上传文件的块时,按照我先前链接的样本,我收到此错误
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://myaccount.blob.core.windows.net/upload-73cca078-9a57-4fd4-a5b9-8012a8bb56bf?sv=2014-02-14&sr=c&si=BlobContainer&sig=mysignature&comp=block&blockid=YmxvY2stMDAwMDAw. This can be fixed by moving the resource to the same domain or enabling CORS.
Chrome控制台也说:
XMLHttpRequest cannot load https://myaccount.blob.core.windows.net/upload-73cca078-9a57-4fd4-a5b9-8012…6mwSBkT67KIJFrTmwpSNN9slSAq0rbiLxRc%3D&comp=block&blockid=YmxvY2stMDAwMDAw. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://localhost:444' is therefore not allowed access
因为我已经启用它,所以我不明白。 我的网络应用程序在https。
上的localhost,端口444上运行XHR请求如下:
function commitBlockList() {
var uri = submitUri + '&comp=blocklist';
console.log(uri);
var requestBody = '<?xml version="1.0" encoding="utf-8"?><BlockList>';
for (var i = 0; i < blockIds.length; i++) {
requestBody += '<Latest>' + blockIds[i] + '</Latest>';
}
requestBody += '</BlockList>';
console.log(requestBody);
$.ajax({
url: uri,
type: "PUT",
data: requestBody,
beforeSend: function (xhr) {
xhr.setRequestHeader('x-ms-blob-content-type', selectedFile.type);
xhr.setRequestHeader('Content-Length', requestBody.length);
xhr.setRequestHeader("x-ms-blob-type", "BlockBlob");
xhr.setRequestHeader("x-ms-date", "Mon, 18 Aug 2014 13:05:21 GMT");
xhr.setRequestHeader("x-ms-version", "2012-02-12");
xhr.setRequestHeader("Authorization", "SharedKey myaccount:d3gXfj6kSp4qVejioDjKQA7dbPyFerDf2iw47RcmGXM=");
},
success: function (data, status) {
console.log(data);
console.log(status);
},
error: function (xhr, desc, err) {
console.log(xhr);
console.log(desc);
console.log(err);
}
});
}
编辑:我在向XHR请求添加一些标题后编辑了这篇文章,以便“#”签名错误&#39;不再存在但是,CORS错误仍然存在。
但是,如果我创建一个文件并使用Web API控制器上传它(所有服务器端,请参阅下面的代码),它可以正常工作:
[HttpGet]
public void Test1() {
PutBlob("upload-73cca078-9a57-4fd4-a5b9-8012a8bb56bf", "test.txt");
}
public string CreateAuthorizationHeader(string canonicalizedstring)
{
var key = "mykey";
string signature = string.Empty;
using (System.Security.Cryptography.HMACSHA256 hmacSha256 = new System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(key)))
{
Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedstring);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
string authorizationHeader = string.Format(CultureInfo.InvariantCulture, "{0} {1}:{2}", "SharedKey", "myaccount", signature);
return authorizationHeader;
}
public void PutBlob(String containerName, String blobName)
{
String requestMethod = "PUT";
String urlPath = String.Format("{0}/{1}", containerName, blobName);
String storageServiceVersion = "2012-02-12";
String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
String content = "my test string";
UTF8Encoding utf8Encoding = new UTF8Encoding();
Byte[] blobContent = utf8Encoding.GetBytes(content);
Int32 blobLength = blobContent.Length;
const String blobType = "BlockBlob";
String canonicalizedHeaders = String.Format(
"x-ms-blob-type:{0}\nx-ms-date:{1}\nx-ms-version:{2}",
blobType,
dateInRfc1123Format,
storageServiceVersion);
String canonicalizedResource = String.Format("/{0}/{1}", "citaviweb", urlPath);
String stringToSign = String.Format(
"{0}\n\n\n{1}\n\n\n\n\n\n\n\n\n{2}\n{3}",
requestMethod,
blobLength,
canonicalizedHeaders,
canonicalizedResource);
String authorizationHeader = CreateAuthorizationHeader(stringToSign);
Uri uri = new Uri(AzureStorage.Default.BlobClient.BaseUri + urlPath);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = requestMethod;
request.Headers.Add("x-ms-blob-type", blobType);
request.Headers.Add("x-ms-date", dateInRfc1123Format);
request.Headers.Add("x-ms-version", storageServiceVersion);
request.Headers.Add("Authorization", authorizationHeader);
request.ContentLength = blobLength;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(blobContent, 0, blobLength);
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
String ETag = response.Headers["ETag"];
}
}
答案 0 :(得分:0)
请确保在设置容器权限后等待30秒,以确保更改生效,并且使用策略ID生成的SAS有效。
此外,您的代码首先检查策略ID是否存在,如果已经存在,则不会更新它。使用该ID生成的SAS令牌将在您首次添加该策略后的第1天停止工作,因为它永远不会使用新的到期日期/时间更新策略。
答案 1 :(得分:0)
好吧,在对Azure进行PUT API调用时,似乎必须在URI中添加blob引用。
var getUploadContainerUrl = function (file) {
var usad = config.accessData.blob;
var url = usad.uri + "/" + file.name + usad.sharedAccessSignature;
return url;
}
我的submitUri javascript变量随后被检索
submitUri = getUploadContainerUrl(file)
其中file是要上传的文件。我没有在url路径中包含file.name属性。我得到的错误无论如何都是误导性的,因为它提到了CORS,而后者却被正确启用了。