无法使用 Rest 从浏览器上传 Azure 存储文件共享文件 API (JavaScript)
Unable to upload Azure Storage File Share File from browser using Rest API (JavaScript)
我正在尝试将文件从浏览器直接上传到文件共享文件。 operation's spec is pretty straight forward, send an HTTP PUT request to a URL (with a SAS token) along with some headers. I attempted to implement this with a simple HTML form and some backing JavaScript in this jsfiddle。令我惊讶的是系统失败,并响应 XML 表明 Content-Length
header 不正确:
<?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
header 不应该存在,或者它应该有一个专门包含 0
的值。我做了一些挖掘,Content-Length is a forbidden header name,这意味着你不能以编程方式调整值。
令我困惑的是,在 Azure Portal 中使用 embeddd Azure 存储资源管理器会跳过某种箍以指定 Content-Length:0
。
我的目标是:
- 从浏览器使用 REST API
- 不引入任何外部库
- 不引入任何服务器
有没有办法从浏览器使用 REST API?
一些我已经检查过的东西:
- 我尝试通过
headers
属性. 强制 Content-Length:0
- 我已确保我的 Azure 存储帐户(用于文件)中的 CORS 设置已更新以说明我的浏览器位置。
- 我尝试与 Blobs 集成作为比较,这在示例中效果很好,但不是我对我的项目感兴趣的东西。
- 我已经尝试在浏览器外使用 API,并且在发送相同的请求时没有问题(当然
Content-Length:0
与规范要求的不同)。
- 我已尝试从 Azure 门户创建的已记录 XHR 中尽可能多地模仿请求 header。
在文件存储中创建文件不同于上传 blob。
在文件存储中,您需要做的第一件事是使用 Create File
REST 操作创建一个空文件。在此操作期间,您在 x-ms-content-length
请求 header.
中指定要创建的文件的大小(内容的长度)
创建空文件后,您可以使用 Put Range
操作发送要写入文件的内容。这是您实际发送内容的地方。您需要使用 Range
或 x-ms-range
请求 header 来指定您希望在该空文件中的确切位置写入您要发送的数据。
基于这些,我修改了你的代码。以下是修改后的方法:
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);
}
我正在尝试将文件从浏览器直接上传到文件共享文件。 operation's spec is pretty straight forward, send an HTTP PUT request to a URL (with a SAS token) along with some headers. I attempted to implement this with a simple HTML form and some backing JavaScript in this jsfiddle。令我惊讶的是系统失败,并响应 XML 表明 Content-Length
header 不正确:
<?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
header 不应该存在,或者它应该有一个专门包含 0
的值。我做了一些挖掘,Content-Length is a forbidden header name,这意味着你不能以编程方式调整值。
令我困惑的是,在 Azure Portal 中使用 embeddd Azure 存储资源管理器会跳过某种箍以指定 Content-Length:0
。
我的目标是:
- 从浏览器使用 REST API
- 不引入任何外部库
- 不引入任何服务器
有没有办法从浏览器使用 REST API?
一些我已经检查过的东西:
- 我尝试通过
headers
属性. 强制 - 我已确保我的 Azure 存储帐户(用于文件)中的 CORS 设置已更新以说明我的浏览器位置。
- 我尝试与 Blobs 集成作为比较,这在示例中效果很好,但不是我对我的项目感兴趣的东西。
- 我已经尝试在浏览器外使用 API,并且在发送相同的请求时没有问题(当然
Content-Length:0
与规范要求的不同)。 - 我已尝试从 Azure 门户创建的已记录 XHR 中尽可能多地模仿请求 header。
Content-Length:0
在文件存储中创建文件不同于上传 blob。
在文件存储中,您需要做的第一件事是使用 Create File
REST 操作创建一个空文件。在此操作期间,您在 x-ms-content-length
请求 header.
创建空文件后,您可以使用 Put Range
操作发送要写入文件的内容。这是您实际发送内容的地方。您需要使用 Range
或 x-ms-range
请求 header 来指定您希望在该空文件中的确切位置写入您要发送的数据。
基于这些,我修改了你的代码。以下是修改后的方法:
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);
}