【问题标题】:Uploading files to azure storage from client从客户端将文件上传到 Azure 存储
【发布时间】:2017-05-05 13:03:50
【问题描述】:

我已经阅读了很多关于直接从客户端/浏览器将文件上传到 Azure 存储的问题。我正在实施的一个来自这个blog,作者是gaurav mantri。在此博客中,他将 SAS url 拆分为路径和查询,然后将文件名附加到路径,然后再次将查询缝合到它。我有没有任何查询的 SAS url。我只有这样的网址

此 SAS 网址中还附加了文件名。在博客中,他附加了 blockId 和 blockList 等。真的需要这样做吗?如果不是,我应该如何提出 PUT 请求?只使用我的 SAS 网址就可以吗?

更新:我已将查询参数(SAS 令牌)包含为“URL?SAS-TOKEN”。现在我收到这样的错误

错误

  dll.vendor.js:44368 PUT https://triggerbackendnormal.blob.core.windows.net/backend-media/a07d312c-6…Vhgoxw/NmD2AeSo4qVhBntrI04xJo1tsqfKJA/7bmQ%3D&comp=block&blockid=undefined 400 (Value for one of the query parameters specified in the request URI is invalid.)CORS

门户中的 CORS 规则设置:

JS代码:

 handleFileSelect(e) {
        var that = this
        maxBlockSize = 256 * 1024;
        currentFilePointer = 0;
        totalBytesRemaining = 0;
        files = e.target.files;
        selectedFile = files[0];
        console.log(selectedFile.name)
        console.log(selectedFile.size)
        console.log(selectedFile.type)
        var fileSize = selectedFile.size;
        if (fileSize < maxBlockSize) {
            maxBlockSize = fileSize;
            console.log("max block size = " + maxBlockSize);
        }
        totalBytesRemaining = fileSize;
        if (fileSize % maxBlockSize == 0) {
            numberOfBlocks = fileSize / maxBlockSize;
        } else {
            numberOfBlocks = parseInt(fileSize / maxBlockSize, 10) + 1;
        }
        console.log("total blocks = " + numberOfBlocks);
        // $("#fileName").text(selectedFile.name);
        // $("#fileSize").text(selectedFile.size);
        // $("#fileType").text(selectedFile.type);

        var baseUrl = 'https://example.blob.core.windows.net/backend-m/a07d312c-6e7a-4281-9e4f-050f5afc4609.mp4?sr=b&se=2017-05-04T15%3A07%3A30Z&sp=w&sv=2016-05-31&sig=SVhgoxw/NmD2AeSo4qVhBntrI04xJo1qfKJA/7bmQ%3D'
        submitUri = baseUrl
        console.log(submitUri);

        this.uploadFileInBlocks();

    }
        //var fileContent = selectedFile.slice(currentFilePointer, currentFilePointer + maxBlockSize);
        //currentFilePointer =+ maxBlockSize;





    uploadFileInBlocks() {
        if (totalBytesRemaining > 0) {
            console.log("current file pointer = " + currentFilePointer + " bytes read = " + maxBlockSize);
            var fileContent = selectedFile.slice(currentFilePointer, currentFilePointer + maxBlockSize);
            var blockId = blockIdPrefix + this.pad(blockIds.length, 6);
            console.log("block id = " + blockId);
            blockIds.push(btoa(blockId));
            reader.readAsArrayBuffer(fileContent);
            currentFilePointer += maxBlockSize;
            totalBytesRemaining -= maxBlockSize;
            if (totalBytesRemaining < maxBlockSize) {
                maxBlockSize = totalBytesRemaining;
            }
        } else {
            this.commitBlockList();
        }
    }

    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);
            },
            success: function (data, status) {
                console.log(data);
                console.log(status);
            },
            error: function (xhr, desc, err) {
                console.log(desc);
                console.log(err);
            }
        });

    }
    pad(number, length) {
        var str = '' + number;
        while (str.length < length) {
            str = '0' + str;
        }
        return str;
    }

    render(){

        reader.onloadend = function (evt) {
            if (evt.target.readyState == FileReader.DONE) { // DONE == 2
                var uri = submitUri + '&comp=block&blockid=' + blockIds[blockIds.length - 1];
                var requestData = new Uint8Array(evt.target.result);
                $.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);
                        console.log(percentComplete)
                        this.uploadFileInBlocks();
                    },
                    error: function(xhr, desc, err) {
                        console.log(desc);
                        console.log(err);
                    }
                });
            }
        };

        return (
            <label htmlFor='myInput'>
                <input id="myInput" type="file" ref={(ref) => this.upload = ref} style={{visibility: 'hidden'}} onChange={this.handleFileSelect.bind(this)}/>
                <FloatingActionButton
                    className="floatingButton"
                    backgroundColor='#fb802a'
                    onClick={(e) => this.upload.click() }>
                    <ContentAdd />
                </FloatingActionButton>
            </label>
        )
    }

【问题讨论】:

标签: javascript ajax azure


【解决方案1】:

我有没有任何查询的 SAS 网址。我只有这样的网址 'https://exapmplename.blob.core.windows.net/backend/a074281-9e4f-050f5afc4609.mp4'

这不是 SAS URL。它只是 blob 的 URL。 SAS URL 具有作为查询字符串参数附加到 URL 的共享访问签名参数,例如 sigsesv 等。我建议您创建一个 SAS URL 并使用它。要上传 Blob,SAS URL 必须具有 Write 权限。

他在博客中附加了blockId和blockList等。真的需要吗 这样做?

这取决于!如果您上传 blob 而不使用 Put Blob REST API 将文件分成块,那么您不需要这样做。但是,如果您需要将文件拆分为块并使用Put BlockPut Block List REST API,那么您必须这样做。

如果不是我应该如何提出 PUT 请求?

如果您的文件很小并且具有良好的互联网速度,那么您确实不需要将文件拆分为更小的块并使用Put Blob REST API 一次性上传文件。

【讨论】:

  • 我明白了。我不得不用这个 URL 附加 SAS 令牌,比如 URL?SAS-TOKEN。我纠正了这个错误。但是现在我在控制台中遇到了一些错误。请查看我的问题中的更新。我已经包含了 CORS 规则、我的代码和错误。关于文件大小,我的文件大小超过 500mb,因此我需要分块进行。请帮助我解决有问题的更新。
  • 您的代码何时出现错误?当您上传第一个阻止或提交阻止列表时?
  • 我纠正了那件事。我将 reader.onloadend 放在 render{} 中。我猜这是不正确的(查看有问题的更新)。我应该把 reader.onloadend 放在哪里?我第一次从输入的 onChange 方法调用 uploadFileInBlocks()。
  • 我该怎么办?
  • 我现在很困惑 :)。那么你收到错误了吗?如果是这样,那是什么错误,你从哪里得到它?
【解决方案2】:

对于 ReactJS,应该是这样的

handleFileSelect(e) {
        var that = this
        maxBlockSize = 256 * 1024;
        currentFilePointer = 0;
        totalBytesRemaining = 0;
        files = e.target.files;
        selectedFile = files[0];
        console.log(selectedFile.name)
        console.log(selectedFile.size)
        console.log(selectedFile.type)
        var fileSize = selectedFile.size;
        if (fileSize < maxBlockSize) {
            maxBlockSize = fileSize;
            console.log("max block size = " + maxBlockSize);
        }
        totalBytesRemaining = fileSize;
        if (fileSize % maxBlockSize == 0) {
            numberOfBlocks = fileSize / maxBlockSize;
        } else {
            numberOfBlocks = parseInt(fileSize / maxBlockSize, 10) + 1;
        }
        console.log("total blocks = " + numberOfBlocks);
        // $("#fileName").text(selectedFile.name);
        // $("#fileSize").text(selectedFile.size);
        // $("#fileType").text(selectedFile.type);
    var baseUrl = 'https://example.blob.core.windows.net/backend-media/e7581d7b-a59d-47eb-b8aa-6b6799179b36.mp4?sv=2016-05-31&sr=b&se=2017-05-09T18%3A26%3A07Z&sp=w&sig=TlS/a9RgVT/j7BHztjFZSF2L2skno3Sko%3D'
    submitUri = baseUrl
    console.log(submitUri);

    this.uploadFileInBlocks();

}


loadEnd(evt){
    var that = this;
    if (evt.target.readyState == FileReader.DONE) { // DONE == 2
        var uri = submitUri + '&comp=block&blockid=' + blockIds[blockIds.length - 1];
        var requestData = new Uint8Array(evt.target.result);
        $.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("hi" + status);
                bytesUploaded += requestData.length;
                var percentComplete = ((parseFloat(bytesUploaded) / parseFloat(selectedFile.size)) * 100).toFixed(2);
                console.log(percentComplete)
                that.uploadFileInBlocks();
            },
            error: function(xhr, desc, err) {
                console.log(desc);
                console.log(err);
            }
        });
    }
}

uploadFileInBlocks() {
    if (totalBytesRemaining > 0) {
        console.log("current file pointer = " + currentFilePointer + " bytes read = " + maxBlockSize);
        var fileContent = selectedFile.slice(currentFilePointer, currentFilePointer + maxBlockSize);
        var blockId = blockIdPrefix + this.pad(blockIds.length, 6);
        console.log("block id = " + blockId);
        blockIds.push(btoa(blockId));
        reader.readAsArrayBuffer(fileContent);
        reader.onloadend = this.loadEnd.bind(this);
        currentFilePointer += maxBlockSize;
        totalBytesRemaining -= maxBlockSize;
        if (totalBytesRemaining < maxBlockSize) {
            maxBlockSize = totalBytesRemaining;
        }
    } else {
        this.commitBlockList();
    }
}

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);
        },
        success: function (data, status) {
            console.log(data);
            console.log("hi" + status);
        },
        error: function (xhr, desc, err) {
            console.log(desc);
            console.log(err);
        }
    });

}
pad(number, length) {
    var str = '' + number;
    while (str.length < length) {
        str = '0' + str;
    }
    return str;
}

render(){

    reader.onloadend = function (evt) {
        if (evt.target.readyState == FileReader.DONE) { // DONE == 2
            var uri = submitUri + '&comp=block&blockid=' + blockIds[blockIds.length - 1];
            var requestData = new Uint8Array(evt.target.result);
            $.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);
                    console.log(percentComplete)
                    this.uploadFileInBlocks();
                },
                error: function(xhr, desc, err) {
                    console.log(desc);
                    console.log(err);
                }
            });
        }
    };

    return (

【讨论】:

    猜你喜欢
    • 2014-11-22
    • 2019-04-23
    • 2022-12-15
    • 2016-10-27
    • 2015-06-13
    • 2021-04-02
    • 2017-01-04
    • 2018-01-01
    • 1970-01-01
    相关资源
    最近更新 更多