S3 отклоняет PUT браузера с заранее заданными URL - он думает, что они ПОЛУЧИЛИ
Я пытаюсь загрузить файлы из браузера (Chrome версии 41.0) на S3, используя предварительно назначенный URL-адрес с методом PUT. Я генерирую предварительно назначенный URL на моем сервере, так как он отлично работает из CURL:
curl -X PUT "Content-Type:" --data "junk" "https://mypresignedurl"
Я сейчас пытаюсь загрузить из браузера с помощью jQuery:
$.ajax({
url: "https://mypresignedurl",
method: 'PUT', // I've also tried type: 'PUT'
data: "junk",
})
Это отклонено AWS с кодом SignatureDoesNotMatch. Ошибка указывает:
<StringToSign>GET 1427216999 /mybucket/myfile</StringToSign>
Но я не использовал GET - я использовал PUT. Если я проверяю вкладку сети Chrome, она правильно отображает запрос как PUT. Так почему же AWS интерпретирует запросы PUT браузера как GET и отклоняет их?
(Похоже, что это не связано с CORS. Я установил CORS в своем сегменте, а затем протестировал из CURL, используя -H "Origin: http://elsewhere.com/". Я также попытался вместо этого передать "type" "method". Я пытался использовать POST вместо PUT - даже тогда AWS по-прежнему перечисляет StringToSign в качестве GET. Я пробовал различные contentTypes. FWIW, моя логика загрузки presigned URL все прекрасно работает из.NET в приложении WPF.)
1 ответ
Хорошо, получил это работает. Теперь я могу загружать из браузера, используя предварительно назначенные URL-адреса.
Меня оттолкнуло то, что S3 интерпретировал мои PUT как GET. Но это на самом деле неправильно. Чтобы выяснить проблему с разрешениями, я посмотрел на вкладке сети Chrome. Перед запросом PUT на S3 был запрос OPTIONS к той же конечной точке S3. Я нажал на это, чтобы получить больше информации, и именно тогда я увидел SignatureDoesNotMatch
сообщение с <StringToSign>GET ... </StringToSign>
Но нажатие на эту ссылку в браузере заставило браузер попытаться получить ресурс от S3. И это не то, что вы должны делать с этим. Запрос извлекается методом OPTIONS. Вы можете сделать это вручную с curl -X OPTIONS ...
если вы действительно хотите, и тогда в нем правильно указано, как можно получить доступ к этому URL. Но не нажимайте на него в браузере, иначе браузер попытается его получить, выдав бессмысленное сообщение, которое не имеет ничего общего с вашим исходным запросом PUT.
Так почему же я получил ошибку при загрузке? Оказывается, я ухожу content-type
пустой. Браузер явно не любит это и превращает его в " , text/plain ..."
, Кажется, что curl и.net, с другой стороны, в порядке с пустым content-type
Отсюда и расхождение в их поведении. Когда я использовал то же самое content-type = "text/plain"
и при генерации заранее заданного URL на сервере, и при загрузке ajax все работало.