Как сделать XMLHttpRequest кросс-домен с помощью Credentials, авторизацией HTTP (CORS)?
Я не могу выполнить кросс-доменный запрос с заголовком авторизации (тестирование с помощью Firefox). У меня есть запросы, работающие без аутентификации, но как только я установил withCredentials
в true, я больше не могу читать ответ с сервера.
На сервере я отправляю эти заголовки (используя метод after_request
в Flask):
resp.headers['Access-Control-Allow-Origin'] = '*'
resp.headers['Access-Control-Allow-Credentials'] = 'true'
resp.headers['Access-Control-Allow-Methods'] = 'POST, OPTIONS'
resp.headers['Access-Control-Allow-Headers'] = 'Authorization'
Никакой вызов OPTIONS на самом деле не выполняется Firefox. На клиенте я вызываю вызов XMLHttpRequest:
var xhr = new XMLHttpRequest()
xhr.open( 'POST', 'http://test.local:8002/test/upload', true)
xhr.withCredentials = true
xhr.onreadystatechange = function() {
console.log( xhr.status, xhr.statusText )
}
xhr.send(fd)
Без withCredentials
установить оператор журнала будет записывать ожидающую информацию на консоль. Как только я установил значение, однако xhr не разрешает доступ, и я просто пишу значение 0 и пустую строку. Я не задал здесь заголовок авторизации, но это не должно повлиять на мою способность читать результат.
Если я попытаюсь добавить имя пользователя/пароль в команду "open", я получаю ошибку NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
.
Что я делаю неправильно?
Ответы
Ответ 1
Я написал статью с полной настройкой CORS.
Я нашел несколько проблем, которые могут привести к этой проблеме:
-
Access-Control-Allow-Origin
не может быть подстановочным знаком, если используются учетные данные. Проще всего просто скопировать заголовок Origin
запроса в это поле. Непонятно, почему стандарт запрещает шаблон.
- Firefox кэширует результаты Access-Control, даже если вы очищаете кеш (возможно, для сеанса). Перезапуск заставил его выполнить новый запрос
OPTIONS
. Чтобы помочь в отладке, я добавил заголовок Access-Control-Max-Age: 1
- Имя пользователя/пароль для команды
open
, по-видимому, не используется в качестве учетных данных. Вы должны добавить заголовок Authorization
самостоятельно. xhr.setRequestHeader( 'Authorization', 'Basic ' + btoa( user + ':' + pass ) )
В целом система withCredentials
является довольно braindead. Легче просто написать сервер, который принимает авторизацию как часть тела запроса.