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 все работало.

Другие вопросы по тегам