CORS, Amazon S3 и Rails - сбои в IE 10 и Safari
IE 10 поддерживает CORS.
Amazon S3 поддерживает CORS.
Мы загружаем прямую связь с сайтом-S3 во всех браузерах, но IE 10 (не беспокоясь о IE 9-). Он работает следующим образом:
-
Пользователь выбирает файл (перетаскивание или выбор из ввода файла)
-
(POST) Мы должны "подписать" запрос до того, как он перейдет на S3 ($.post('/static/sign_asset', { ... }
), который имеет обратный вызов, который срабатывает отлично весь день.
-
(POST) Затем мы превращаем XHR в S3 с данными файла и данными из подписи и т.д.
var xhr = new XMLHttpRequest();
// etc
var fd = new FormData();
// etc
xhr.open('POST', url, true);
xhr.send(fd);
Загрузка файлов, все работает отлично во всех браузерах, кроме...
Проблемы запускаются в IE 10:
-
Исходный нуль не найден в заголовке Access-Control-Allow-Origin. и XMLHttpRequest: ошибка сети 0x80070005, доступ запрещен. Никакие другие браузеры не отображаются это после того, как мы установили response.headers["Access-Control-Allow-Origin"] = "*"
в контроллер, который отправляет ответ. Даже если мы ошибались, Chrome покажет эту ошибку, но запрос все равно пройдет.
-
Файл фактически загружается на S3, несмотря на эту ошибку. Amazon S3 делает это 303 вещь перенаправления - это наша проверка того, что файл был успешно загружен.
-
(GET) Это перенаправление на запрос CORS Ajax, поэтому "перенаправление" не обновляет страницу, на которую он только что возвращается, и попадает на наши серверы. IE 10 делает этот запрос с
Content-Type multipart/form-data; boundary=---------------------------7dd2ce2201da
Это то, что приводит к ошибке Rails.
Started GET "/static/signed/asset/tsabat/83ee6840-7158-0130-c19b-28cfe912f6ff?bucket=s.cdpn.io&key=5%2Fauthor-tim_2.jpg&etag=%2260fb3876d516553ff6f3a018066b3250%22" for 127.0.0.1 at
2013-03-17 10:46:36 -0700
EOFError - bad content body:
(gem) rack-1.4.5/lib/rack/multipart/parser.rb:74:in `block in Rack::Multipart::Parser#fast_forward_to_first_boundary' (gem) rack-1.4.5/lib/rack/multipart/parser.rb:72:in `Rack::Multipart::Parser#fast_forward_to_first_boundary'
(gem) rack-1.4.5/lib/rack/multipart/parser.rb:72:in `Rack::Multipart::Parser#parse'
(gem) rack-1.4.5/lib/rack/multipart/parser.rb:15:in `Rack::Multipart.parse_multipart'
(gem) rack-1.4.5/lib/rack/multipart.rb:25:in `ActionDispatch::Request#parse_multipart'
(gem) rack-1.4.5/lib/rack/request.rb:336:in `ActionDispatch::Request#POST'
(gem) rack-1.4.5/lib/rack/request.rb:201:in `ActionDispatch::Request#POST'
Сафари тоже не работает (6.0.2)
Safari возвращает код состояния 200, а Rails не беспокоится о перенаправлении, но xhr.status ошибочен. xhr.readyState == 4, но xhr.status == 0. Мы искали 200, чтобы убедиться, что он работает нормально. Это достаточно легко исправить, но все же...
Chrome делает отлично - Кажется, даже не установлен Content-Type
Firefox отлично работает - Content-Type application/json; charset=utf-8
Есть примеры страниц, которые показывают, насколько хорошо IE 10 обрабатывает CORS, но они не занимаются этой проблемой перенаправления.
Ответы
Ответ 1
Член команды CodePen здесь. Мы это поняли...
Мы хотели зависеть от перенаправления 303, встроенного в S3 POST, но оказалось, что это было проблематично, как показано выше. Вместо этого мы просто перестали использовать поле формы S3 success_action_redirect
и переключились на success_action_status
.
Для потомков не зависеть от перенаправления S3 303, чтобы последовательно работать в браузерах для запросов xhr. Если вы это сделаете, вы потратите свое время на борьбу с недопустимыми заголовками, нулевым происхождением и драконами.