Начиная с версии Chrome 37, запросы на междоменные запросы не выполняются (снова), если сервер имеет аутентификацию, даже если все заголовки CORS установлены правильно. Это включено localhost
(мой dev ПК).
Некоторым из вас может быть известно об истории ошибок Chrome / CORS / auth, особенно при использовании HTTPS. Моя проблема не связана с HTTPS: у меня есть приложение AngularJS, используемое для localhost:8383
разговора с сервером Java (Jetty), на localhost:8081
котором активирован HTTP BASIC. GET работает нормально, но POST не работают с 401:
XMLHttpRequest cannot load http://localhost:8081/cellnostics/rest/patient.
Invalid HTTP status code 401
Я ранее написал пользовательский (Java) фильтр CORS, который устанавливает правильные заголовки CORS, которые работали до v36. Он терпит неудачу в v37, а также последний v38 (38.0.2125.101 м). Он по- прежнему работает в Internet Explorer 11 (11.0.9600) и Opera 12.17 (сборка 1863).
Запросы GET успешны, но POST не работают. Похоже, что Chrome предварительно отправляет все мои POST-сообщения из-за withCredentials: «application / json» и что это запрошенный запрос OPTIONS, который терпит неудачу.
В приложении «Угловое» я явно устанавливаю следующие заголовки запросов. AFAIK этот параметр //Enable cross domain calls $httpProvider.defaults.useXDomain = true; //Send all requests, even OPTIONS, with credentials $httpProvider.defaults.withCredentials = true;
должен гарантировать, что учетные данные отправляются даже для запросов OPTIONS:
Access-Control-Allow-Methods
Ниже приведен запрос / ответ. Вы можете видеть, что метод OPTIONS включен в Access-Control-Allow-Origin: http://localhost:8383
заголовке. Вы можете также видеть , что происхождение этого приложения в JavaScript явно включено: Remote Address:[::1]:8081 Request URL:http://localhost:8081/cellnostics/rest/medicaltest Request Method:OPTIONS Status Code:401 Full authentication is required to access this resource Request headers: Accept:*/* Accept-Encoding:gzip,deflate,sdch Accept-Language:en-US,en;q=0.8,af;q=0.6 Access-Control-Request-Headers:accept, content-type Access-Control-Request-Method:POST Connection:keep-alive Host:localhost:8081 Origin:http://localhost:8383 Referer:http://localhost:8383/celln-web/index.html User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.101 Safari/537.36 Response headers: Access-Control-Allow-Credentials:true Access-Control-Allow-Headers:Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With, Accept Access-Control-Allow-Methods:POST, GET, OPTIONS, PUT, DELETE Access-Control-Allow-Origin:http://localhost:8383 Access-Control-Max-Age:3600 Content-Length:0 Server:Jetty(8.1.8.v20121106) WWW-Authenticate:Basic realm="Cellnostics"
.
t=108514 [st=0] +URL_REQUEST_START_JOB [dt=4]
--> load_flags = 336011264 (BYPASS_DATA_REDUCTION_PROXY | DO_NOT_SAVE_COOKIES | DO_NOT_SEND_AUTH_DATA | DO_NOT_SEND_COOKIES | MAYBE_USER_GESTURE | VERIFY_EV_CERT)
--> method = "OPTIONS"
--> priority = "LOW"
--> url = "http://localhost:8081/cellnostics/rest/patient"
...
t=108516 [st=2] HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> OPTIONS /cellnostics/rest/patient HTTP/1.1
Host: localhost:8081
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:8383
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.101 Safari/537.36
Access-Control-Request-Headers: accept, content-type
Accept: */*
Referer: http://localhost:8383/celln-web/index.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,af;q=0.6
Кто-нибудь понял, что мне еще нужно делать? Я попытался очистить кеш Chrome перед тестированием, перезапуском и убедиться, что перед перезагрузкой не осталось фоновых процессов Chrome, поэтому я уверен, что не было никаких длительных проблем с кешем кэша.
Мне пришлось переключиться на IE 11 для тестирования моей веб-разработки. Тот факт, что одна и та же настройка клиента и сервера по-прежнему работает для IE и Opera, а также тот факт, что есть история ошибок Chrome / CORS, заставляет меня подозревать Chrome.
EDIT: Вот выдержка из списка событий net-internals в Chrome:
withCredentials = true
Таким образом, похоже, что заголовок авторизации не отправляется с предварительным полем OPTIONS, хотя я явно задал Content-Type
.
Однако почему IE и Opera все еще работают? Является ли Chrome более стандартизированным в этом отношении? Почему это сработало, а затем началось с отказа от версии v37?
EDIT: инструменты Chrome dev не показывают Content-Type
запрос на свалках выше, но здесь он из журнала сети. Первая фотография показывает POST, когда аутентификация сервера отключена, а тип контента правильно отправлен как «application / json». Второй рис., Когда включен auth, показывая, что запрос OPTIONS не работает (кажется, OPTIONS всегда отправляется с типом контента «text / plain»?).