3

为了将使用 HTML5/Javascript 的文件直接上传到 blob 存储中,我关注了 Gaurav Mantri 的这篇精彩文章。

http://gauravmantri.com/2013/02/16/uploading-large-files-in-windows-azure-blob-storage-using-shared-access-signature-html-and-javascript/

但是我发现在上传部分他的这部分代码失败并出现 403 错误。

有趣的是,这是随机发生的。有时上传确实有效,并且一切都成功完成,但大多数时候它会因 403 错误而失败。

需要注意的一件事:我希望很快将 CORS 支持添加到 Azure,但是暂时我正在使用 Chrome(带有chrome.exe --disable-web-security选项)来解决这个问题。

PUT https://mystorage.blob.core.windows.net/asset-38569007-3316-4350 …Giv17ye4bocVWDbA/EQ+riNiG3wEGrFucbd1BKI9E=&comp=block&blockid=YmxvY2stMA==

403(服务器无法验证请求。确保 Authorization 标头的值正确形成,包括签名。)

$.ajax({
    url: uri,
    type: "PUT",
    data: requestData,
    processData: false,
    beforeSend: function(xhr) {
        xhr.setRequestHeader('x-ms-blob-type', 'BlockBlob');
        xhr.setRequestHeader('Content-Length', requestData.length);
    },
    success: function (data, status) {
        console.log(data);
        console.log(status);
        bytesUploaded += requestData.length;
        var percentComplete = ((parseFloat(bytesUploaded) / parseFloat(selectedFile.size)) * 100).toFixed(2);
        $("#fileUploadProgress").text(percentComplete + " %");
        uploadFileInBlocks();
    },
    error: function(xhr, desc, err) {
        console.log(desc);
        console.log(err);
    }
});

在实际开始上传部分之前,我在 Azure 中创建资产/定位器/文件后延迟了 30 秒,以便为传播定位器留出时间。

对我可能遗漏的内容有什么建议吗?

4

2 回答 2

2

非常感谢 Gaurav 为我指明了问题的方向。

事实证明,我正在对服务器进行 JSON 调用,该服务器将创建资产/定位器/策略,然后返回上传 uri。

但是,我的上传 uri 是Uri类型,当 JSON 对其进行序列化时,它没有正确编码。

将我的 uri 对象(在服务器上)更改为字符串(并调用uploaduri = (new UriBuilder(theuri)).ToString();)返回到 Web 客户端的 uri 已正确编码,我不再收到 403 错误.

因此,请注意其他人,如果您遇到同样的问题,您可能需要查看上传 uri 的编码。

于 2013-07-04T16:39:11.620 回答
0

Gaurav 这是我用来创建空资产(带定位器和文件)的代码:

/// <summary>
/// Creates an empty asset on Azure and prepares it to upload
/// </summary>
public FileModel Create(FileModel file)
{
    // Update the file model with file and asset id
    file.FileId = Guid.NewGuid().ToString();

    // Create the new asset
    var createdAsset = this.Context.Assets.Create(file.AssetName.ToString(), AssetCreationOptions.None);

    // Create the file inside the asset and set its size
    var createdFile = createdAsset.AssetFiles.Create(file.Filename);
    createdFile.ContentFileSize = file.Size;

    // Create a policy to allow uploading to this asset
    var writePolicy = this.Context.AccessPolicies.Create("Policy For Copying", TimeSpan.FromDays(365 * 10), AccessPermissions.Read | AccessPermissions.Write | AccessPermissions.List);

    // Get the upload locator
    var destinationLocator = this.Context.Locators.CreateSasLocator(createdAsset, writePolicy);

    // Get the SAS Uri and save it to file
    var uri = new UriBuilder(new Uri(destinationLocator.Path));
    uri.Path += "/" + file.Filename;
    file.UploadUri = uri.Uri;

    // Return the updated file
    return file;
}
于 2013-07-02T18:42:00.250 回答