В запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin» + ответ имеет код состояния HTTP 401.

XMLHttpRequest не может загрузить http://192.168.1.253:8080/... Нет 'Access-Control-Allow- Заголовок Origin присутствует на запрошенном ресурсе. Таким образом, доступ к источнику 'http://localhost:4200' запрещен. В ответе был код состояния HTTP 401.

Довольно распространенная ошибка с большим количеством возможных решений, которые не сработали. Я понимаю (я думаю), как должен работать CORS, и я не вижу ничего плохого в своих HTTP-заголовках, но это все равно не работает.

Из Chrome:

Request URL:http://192.168.1.253:8080/...
Request Method:OPTIONS
Status Code:200 OK
Remote Address:192.168.1.253:8080
Referrer Policy:no-referrer-when-downgrade
Response Headers
Access-Control-Allow-Headers:x-requested-with,accept,content-
type,authorization
Access-Control-Allow-Methods:POST, GET, PUT, PATCH, OPTIONS, DELETE
Access-Control-Allow-Origin:*
Access-Control-Max-Age:3600
Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Connection:keep-alive
Content-Length:0
Date:Mon, 15 May 2017 21:50:55 GMT
Expires:0
Pragma:no-cache
Server:...
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block
Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:authorization,content-type
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:192.168.1.253:8080
Origin:http://localhost:4200
Pragma:no-cache
Referer:http://localhost:4200/...
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 
(KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36

Насколько я понимаю, для ответа OPTIONS требуется набор заголовков Access-Control-Allow-Origin и разрешение типа метода и значений заголовка, что он и делает.

Соответствующий угловой ниже. Я сделал довольно много разных комбинаций этого со всевозможными вещами в заголовке, но ничего не работает.

private getObject<T>(path: string): Promise<T> {
    return this.http.get(SERVER_URL + path, this.authenticationToken())
        .toPromise()
        .then(response => response.json() as T)
        .catch(this.handleError);
}

private authenticationToken() : RequestOptions {
    let login = JSON.parse(sessionStorage.getItem('currentLogin'));
    if (login && login.authenticationToken) {
        let headers = new Headers({ 
            'Authorization': 'Basic ' + login.authenticationToken,
            'Content-type': 'application/json', 
          });
        return new RequestOptions({ headers: headers });
    }
}

У меня такое чувство, что я упускаю что-то очевидное, но это сводит меня с ума, любая помощь приветствуется. Обратите внимание, что это работает с уже существующим приложением Ember, поэтому я не думаю, что это сервер.


person Lyle Rolleman    schedule 15.05.2017    source источник
comment
Когда вы пытаетесь использовать Access-Control-Allow-Origin:localhost:4200 — вместо * явно укажите URL — работает ли это ?   -  person Eeks33    schedule 16.05.2017
comment
На самом деле это не ваш интерфейс или ваши запросы. Ваш бэкэнд должен быть настроен для разрешения доступа CORS. То, что вы возвращаете, на самом деле является мерой безопасности Chrome. Я не говорю, что это решит все ваши проблемы (401), но пока вы не разберетесь, как настроить CORS на своем бэкенде, это хорошее расширение, чтобы заставить Chrome заткнуться: chrome.google.com/webstore/detail/allow-control-allow-origi/   -  person joh04667    schedule 16.05.2017
comment
@Eeks33 Боюсь, нет   -  person Lyle Rolleman    schedule 16.05.2017
comment
@ joh04667 joh04667 Спасибо за плагин, хотя я не понимаю, как это может быть бэкэнд, поскольку он работает с другим приложением.   -  person Lyle Rolleman    schedule 16.05.2017
comment
Поскольку это связано с внутренним сервером, вам необходимо определить технологию, на которой он работает, и опубликовать / пометить соответствующим образом. Угловой код - это только запросы на стороне клиента и, следовательно, не имеет ничего общего с CORS.   -  person NitinSingh    schedule 11.04.2018


Ответы (2)


В ответе был код состояния HTTP 401.

401 указывает на ошибку аутентификации. Сообщение об ошибке в вопросе не относится к ответу на предварительный запрос OPTIONS. Вместо этого кажется, что это для фактического запроса GET, который вы пытаетесь отправить.

Таким образом, судя по этому сообщению об ошибке, наиболее вероятным сценарием является то, что предварительный OPTIONS запрос браузера был выполнен успешно, но ваш GET запрос не выполнен из-за сбоя аутентификации.

Итак, сервер возвращает страницу ответа/ошибки 401. И многие/большинство веб-серверов не настроены на отправку заголовка ответа Access-Control-Allow-Origin для ответов/страниц с ошибками. Это единственная причина, по которой вы также получаете сообщение об отсутствии этого заголовка.

Но этот отсутствующий заголовок для ответа об ошибке не является причиной вашей проблемы; вместо этого 401.

Итак, кажется, вы, вероятно, хотите выяснить, что заставляет сервер отправлять ответ 401 — почему вы получаете ошибку аутентификации. Если вы исправите это, вполне вероятно, что вы получите ответ от сервера, который включает заголовок ответа Access-Control-Allow-Origin, как и ожидалось.

person sideshowbarker    schedule 16.05.2017

Это типичная ошибка, возникающая при работе с Angular и Ionic. Проблема возникает из-за того, что когда ваше приложение загружается в браузере, ваше приложение загружает весь контент из происхождения, который поступает с вашего локального адреса http://localhost:4200, затем, когда вы хотите отправить любой запрос AJAX на другой хост, отличный от localhost:4200 , запрос вызывается из любой точки, отличной от происхождения, для этого требуется CORS (ресурс кросс-происхождения Совместное использование) предварительный запрос, чтобы узнать, может ли он получить доступ к ресурсу.

Решение заключается в использовании прокси-сервера, с помощью которого вы можете перехватить определенные URL-адреса и отправить их на внутренний сервер. Реализация проста:

1.- Создайте файл proxy.conf.js в корневой папке вашего проекта.

2.- Настройте прокси-сервер, поместите его в файл proxy.conf.js, предполагая, что ваш новый хост находится в http://localhost:3000.

const PROXY_CONFIG = [
    {
        context: [
            "/my",
            "/many",
            "/endpoints",
            "/i",
            "/need",
            "/to",
            "/proxy"
        ],
        target: "http://localhost:3000",
        secure: false
    }
]

module.exports = PROXY_CONFIG;

3.- Измените файл package.json, вставив этот "start": "ng serve --proxy-config proxy.conf.js",

4.- В вашей службе немного измените путь вашего запроса с этого http://localhost:3000/endpoints/any/path/that/you/use на этот ../endpoints/any/path/that/you/use (при условии, что другой хост находится в localhost:3000, а контекст - /endpoints).

5.- Запустить angular из корневой папки с: npm start ; это выполнить ng serve с параметрами прокси.

Если вам нужна дополнительная информация об этом, проверьте прокси. для бэкенда документации Angular Cli

person havelino    schedule 13.09.2017
comment
Пожалуйста, не публикуйте одинаковые ответы на несколько вопросов. Опубликуйте один хороший ответ, затем проголосуйте/отметьте, чтобы закрыть другие вопросы как дубликаты. Если вопрос не повторяется, адаптируйте свои ответы к вопросу. - person rene; 13.09.2017
comment
Почему в этой строке есть .js вместо .json? - 3.- Измените файл package.json, вставив следующее начало: ng serve --proxy-config proxy.conf.js, - person 151291; 22.12.2017
comment
Это файл js, поскольку конфигурации экспортируются с экспортом модуля, узел js интерпретирует эту конфигурацию как константу во время запуска скрипта запуска. - person havelino; 05.01.2018