【问题标题】:Unable to upload Azure Storage File Share File from browser using Rest API (JavaScript)无法使用 Rest API (JavaScript) 从浏览器上传 Azure 存储文件共享文件
【发布时间】:2020-09-17 12:07:51
【问题描述】:

我正在尝试将文件从浏览器直接上传到文件共享文件。 operation's spec 非常简单,向 URL(带有 SAS token)发送 HTTP PUT 请求以及一些标头。我试图在jsfiddle 中使用一个简单的 HTML 表单和一些支持 JavaScript 来实现这一点。令我惊讶的是,系统出现故障,并响应 XML 指示 Content-Length 标头不正确:

<?xml version="1.0" encoding="utf-8"?>
<Error>
  <Code>InvalidHeaderValue</Code>
  <Message>The value for one of the HTTP headers is not in the correct format.
RequestId:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
Time:0000-00-00T00:00:00.0000000Z</Message>
  <HeaderName>Content-Length</HeaderName>
  <HeaderValue>12345</HeaderValue>
</Error>

我仔细检查了文档,它表明Content-Length 标头不应该存在,或者它应该有一个专门包含0 的值。我做了一些挖掘,Content-Length 是一个forbidden header name,这意味着你不能以编程方式调整值。

令我困惑的是,使用 Azure Portal 中的嵌入 Azure 存储资源管理器会跳过某种圈子以指定 Content-Length:0

我的目标是:

  • 在浏览器中使用 REST API
  • 不引入任何外部库
  • 不引入任何服务器

有没有办法从浏览器使用 REST API?

我已经检查过的一些事情:

  • 我尝试通过 headers 属性强制使用 Content-Length:0
  • 我已确保我的 Azure 存储帐户(用于文件)中的 CORS 设置已更新以考虑我的浏览器的位置。
  • 我尝试与 Blobs 集成作为比较,这在示例中效果很好,但不是我对我的项目感兴趣的。
  • 我已经尝试在浏览器外使用 API,并且发送相同的请求没有问题(当然 Content-Length:0 会按照规范的要求偏离)。
  • 我已尝试从 Azure 门户制作的已记录 XHR 中尽可能多地模仿请求标头。

【问题讨论】:

    标签: javascript azure http azure-storage azure-storage-files


    【解决方案1】:

    在文件存储中创建文件与上传 Blob 不同。

    在文件存储中,您需要做的第一件事是使用Create File REST 操作创建一个空文件。在此操作期间,您在 x-ms-content-length 请求标头中指定要创建的文件大小(您的内容长度)。

    创建空文件后,您可以使用Put Range 操作发送要写入文件的内容。这是您实际发送内容的地方。您需要使用Rangex-ms-range 请求标头来指定您希望在该空文件中的确切位置写入要发送的数据。

    基于这些,我修改了您的代码。以下是修改后的方法:

    async function upload(url, headers, content) {           
        if (!url) { return; }
    
        const init = {
            method: 'PUT',
            body: content,
            headers: headers
        };
        console.log(init);
        const response = await fetch(url, init);
    
        document.getElementById('response-content').innerText = await response.text();
    }
    
    async function uploadToFileStorage() {
        console.log('creating empty file');
        const url = document.getElementById('url').value;
        const content = document.getElementById('content').value;
        const headers = {
          'content-length': 0,
          'x-ms-type': 'file',
          'x-ms-content-length': content.length
        }
        await upload(url, headers, '');
        console.log('empty file created.');
        const url2 = url + '&comp=range';
        const headers2 = {
            'Content-Length': content.length,
            'x-ms-version': '2015-02-21',
            'Range': 'bytes=0-' + (content.length-1),
            'x-ms-write': 'update'
        };
        await upload(url2, headers2, content);
    }
    

    【讨论】:

    • 感谢您的快速回复!看到这个之后,我可以看到我是如何忽略了 Azure 门户实现的,因为我错过了第一个请求没有内容的事实。
    猜你喜欢
    • 1970-01-01
    • 2021-11-05
    • 2021-12-05
    • 2020-02-13
    • 2013-03-18
    • 1970-01-01
    • 2021-10-20
    • 2018-08-09
    • 2016-10-15
    相关资源
    最近更新 更多