Невозможно загрузить Azure файл общего доступа к файлам хранилища из браузера с помощью Rest API (JavaScript) - PullRequest
0 голосов
/ 29 мая 2020

Я пытаюсь загрузить файл из браузера прямо в файл общего доступа. Операция spe c довольно проста: отправьте HTTP-запрос PUT на URL-адрес (с токеном SAS ) вместе с некоторыми заголовками. Я попытался реализовать это с помощью простой формы HTML и некоторой поддержки JavaScript в этом jsfiddle . К моему удивлению, система не работает и отвечает 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 - это запрещенное имя заголовка , что означает, что вы не можете настроить значение программно.

К моей загадке, используя embe ddd Azure Storage Explorer внутри Azure Portal перепрыгивает через какие-то обручи, чтобы указать Content-Length:0.

Мои цели:

  • Использовать REST API из браузера
  • Не вводить никаких внешних библиотек
  • Не вводить какие-либо серверы

Есть ли способ использовать REST API из браузер?

Некоторые вещи, которые я уже проверил:

  • Я пробовал принудительно использовать Content-Length:0 через свойство headers.
  • Я удостоверился, что Настройки CORS в моей учетной записи хранения Azure (для файлов) были обновлены для учета местоположения моего браузера.
  • Я попытался интегрировать с Blobs в качестве сравнения, который отлично работает в образец, но не то, что меня интересует для моего проекта.
  • У меня есть e попытался работать с API из браузера, и у меня нет проблем с отправкой в ​​том же запросе (конечно, Content-Length:0 отклоняется в соответствии с требованиями спецификации).
  • Я пробовал имитировать заголовки запроса как можно больше насколько это возможно из записанного XHR, сделанного с портала Azure.

1 Ответ

1 голос
/ 30 мая 2020

Создание файла в хранилище файлов отличается от загрузки большого двоичного объекта.

В хранилище файлов первое, что вам нужно сделать, это создать пустой файл с помощью операции Create File REST . Во время этой операции вы указываете размер файла, который вы sh создаете (длина вашего контента) в x-ms-content-length заголовке запроса.

После создания пустого файла вы отправляете контент для записи в файл используя операцию Put Range. Именно сюда вы отправляете контент. Вам нужно будет использовать заголовок запроса Range или x-ms-range, чтобы указать, где именно в этом пустом файле вы будете sh записывать отправляемые данные.

На их основе я изменил ваш код. Вот модифицированные методы:

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);
}
...