У меня есть приложение MVC, которое позволяет пользователю загружать ресурс в хранилище BLOB-объектов с помощью динамически генерируемого SAS. Пользователь выберет файл и нажмет «Загрузить». При нажатии кнопки «Загрузить» в действие контроллера отправляется вызов ajax, который генерирует SAS для контейнера и возвращает строку, которая является URI для большого двоичного объекта, который будет загружен с добавленной подписью. Это отлично работает и возвращает правильный URI с SAS. Затем у меня есть еще один вызов ajax, который поместит данные из файла в хранилище BLOB-объектов Azure, используя возвращенный URI. Когда это выполняется, я получаю ошибку времени выполнения javascript в файле Jquery.min с надписью «0x80070005 Access is Denied».
Я хотел убедиться, что я закодировал это правильно и что мой SAS был правильным, поэтому я запустил его через Runscope (у меня было действие контроллера MVC, чтобы изменить URI для прохождения через мою учетную запись Runscope). Если я скопировал URI и вручную установил заголовки, которые я устанавливаю в вызове ajax, это сработало. И настройки разрешений работают. С созданным мной SAS я могу получить доступ к файлу, без него я не могу. Если я позволю ему пройти через мой файл javascript с вызовом ajax, он потерпит неудачу и вернет ошибку 405. Вот мой вызов ajax, а затем два разных запроса, отправленных с помощью Runscope.
Я использовал эту статью http://gauravmantri.com/2013/02/16/uploading-large-files-in-windows-azure-blob-storage-using-shared-access-signature-html-and-javascript/#comment-1700 в качестве руководства для загрузки файла по частям. Следующий ajax-вызов будет выполняться для каждого загруженного блока, но с первой попытки произойдет сбой.
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() {
// successful stuff here
uploadFileInBlocks();
}
error: function (xhr, desc, err) {
// error stuff here
}
});
И вот мои результаты Runscope:
Успешный ручной запрос:
PUT https://<myaccount>.blob.core.windows.net/trainingcourseresources/1002/georgewashington.jpg?sr=c&sp=rw&sig=GI+HN1hTEiyTG9Kz1OIBIcArAEkeZWyxI4v7OmMuEsA=&sv=2012-02-12&se=2013-09-17T13:19:52Z
HEADERS
Accept: */*
Accept-Encoding: gzip, deflate, compress
Connection: close
Host: atlastestblob.blob.core.windows.net
User-Agent: runscope/0.1
X-Ms-Blob-Type: BlockBlob
QUERYSTRING
se: 2013-09-17T13:19:52Z
sig: GI+HN1hTEiyTG9Kz1OIBIcArAEkeZWyxI4v7OmMuEsA=
sp: rw
sr: c
sv: 2012-02-12
Response: 201 Created
Неудачный запрос ajax:
OPTIONS https://<myaccount>.blob.core.windows.net/trainingcourseresources/1002/cslewis.jpg?sp=rw&sr=c&blockid=YmxvY2stMDAwMDAw&sv=2012-02-12&sig=iIn/AL3eBBFlZdYoT717SMS9iDOY5PEKIdIufOle7NA=&comp=block&se=2013-09-17T13:40:00Z
HEADERS
Accept: */*
Accept-Encoding: gzip, deflate
Access-Control-Request-Headers: content-type, accept, x-ms-blob-type
Access-Control-Request-Method: PUT
Cache-Control: no-cache
Connection: close
Dnt: 1
Host: atlastestblob.blob.core.windows.net
Origin: https://localhost:44308
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
QUERYSTRING
blockid: YmxvY2stMDAwMDAw
comp: block
se: 2013-09-17T13:40:00Z
sig: iIn/AL3eBBFlZdYoT717SMS9iDOY5PEKIdIufOle7NA=
sp: rw
sr: c
sv: 2012-02-12
Response: 405 The resource doesn't support specified Http Verb