使用JavaScript将文件放入blob存储导致403(服务器无法验证请求)

时间:2013-07-02 17:44:38

标签: azure azure-storage-blobs azure-media-services

我按照Gaurav Mantri的这篇精彩文章,将HTML5 / Javascript文件直接上传到blob存储中。

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

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

有趣的是,这是随机发生的。有时上传实际上是成功的,一切都成功完成,但大部分时间都是因为403错误而失败。

有一点需要注意:我希望很快就会向Azure添加CORS支持但是暂时我正在使用Chrome(使用 chrome.exe --disable-web-security 选项)解决问题。

  

PUT   https://mystorage.blob.core.windows.net/asset-38569007-3316-4350 ... Giv17ye4bocVWDbA / EQ + riNiG3wEGrFucbd1BKI9E =安培;可比=块&安培;块标识= YmxvY2stMA ==

     

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

$.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秒,以便为传播定位器提供时间。

对我可能遗失的任何建议?

2 个答案:

答案 0 :(得分:2)

非常感谢Gaurav将我指向问题的方向。

事实证明,我正在向服务器发出JSON调用,这将调用资产/定位器/策略,然后返回上传uri。

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

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

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

答案 1 :(得分: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;
}