AngularJS не обнаруживает заголовок Access-Control-Allow-Origin?

Я запускаю угловое приложение на локальном виртуальном хосте (http://foo.app:8000). Он делает запрос к другому локальному виртуальному хосту (http://bar.app:8000), используя $http.post.

$http.post('http://bar.app:8000/mobile/reply', reply, {withCredentials: true});

На вкладке «Сеть» инструментов разработчика Chrome я, конечно, вижу запрос OPTIONS, и ответ включает заголовок:

Access-Control-Allow-Origin: http://foo.app:8000

Однако запрос POST отменяется со следующей ошибкой:

В запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin». Таким образом, доступ к источнику 'http://foo.app:8000' запрещен.

Кто-нибудь испытал это? Заголовок Access-Control-Allow-Origin очень четко включен в ответ на запрос OPTIONS, поэтому я не могу понять, почему POST действует, а заголовок отсутствует.

Access-Control-Allow-Credentials также устанавливается на true.


person TaylorOtwell    schedule 13.01.2014    source источник
comment
вы видите заголовок Access-Control-Allow-Methods в ответе OPTIONS?   -  person harun    schedule 14.01.2014
comment
Конечно. Разрешены все методы.   -  person TaylorOtwell    schedule 14.01.2014


Ответы (9)


Это ошибка в хроме для локального разработчика. Попробуйте другой браузер. Тогда это сработает.

person user1469734    schedule 13.01.2014
comment
Спасибо. В файрфоксе работает нормально. У вас есть больше информации об этой ошибке? - person TaylorOtwell; 14.01.2014
comment
На самом деле это не ошибка, а скорее что-то из соображений безопасности. См.: stackoverflow.com/questions/3102819/ - person user1469734; 14.01.2014
comment
Я попробовал в другом браузере, и это сработало @_@ Почему хром такой злой :( - person Bruno Gomes; 12.08.2014
comment
Что вы должны делать, когда будете готовы развернуть приложение для более широкой аудитории, большинство людей используют Chrome, как правильно решить эту проблему? - person Donald N. Mafa; 18.06.2015
comment
Но это не решение!!! Это связано с CORS, а не только с браузерами... Это ограничение безопасности. Вы всегда можете включить CORS на своем сервере. - person Paul Okeke; 09.08.2015

Для тех, кто хочет использовать Chrome, есть обходной путь. Это расширение позволяет запрашивать любой сайт с помощью AJAX из любого источника, поскольку оно добавляет заголовок 'Access-Control-Allow-Origin: *' к ответу.

В качестве альтернативы вы можете добавить этот аргумент в панель запуска Chrome: --disable-web-security. Обратите внимание, что я бы использовал это только для целей разработки, а не для обычного «веб-серфинга». Для справки см. Запуск Chromium с флагами.

И последнее замечание: установив расширение, упомянутое в первом абзаце, вы можете легко включить/отключить CORS.

person Rui Afonso Pereira    schedule 20.09.2014
comment
Дополнительным бонусом является то, что этот очень полезный плагин также мешает работе Facebook, поэтому, если ваш рабочий процесс разработки программного обеспечения похож на мой, вы, вероятно, закончите остальную часть того, над чем вы работали, в рекордно короткие сроки. - person Chris Rae; 14.04.2016
comment
Это правда, @ChrisRae. - person Rui Afonso Pereira; 14.04.2016
comment
Это расширение, по-видимому, устраняет ошибку. Однако, когда я проверил заголовок запроса, он добавил Origin: evil.com. Я не знаю, вредно это или незначительно. - person Isaac Pak; 25.10.2016

Я отправлял запросы из angularjs с помощью службы $http в бутылку, работающую на http://localhost:8090/, и мне пришлось применить CORS, в противном случае я получаю ошибки запроса, такие как "Нет заголовка "Access-Control-Allow-Origin" в запрошенном ресурсе"

from bottle import hook, route, run, request, abort, response

#https://github.com/defnull/bottle/blob/master/docs/recipes.rst#using-the-hooks-plugin

@hook('after_request')
def enable_cors():
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS, PUT'
    response.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept'
person Gabriel    schedule 06.03.2014

Я столкнулся с этой же проблемой. Для меня запрос OPTIONS прошел бы, но запрос POST сказал бы «прервано». Это заставило меня поверить, что браузер вообще никогда не отправлял запрос POST. Chrome сказал что-то вроде «Предупреждающие предварительные заголовки показаны» в заголовках запросов, но заголовки ответов не были показаны. В конце концов я обратился к отладке Firefox, в результате чего обнаружил, что мой сервер отвечает с ошибкой, а в ответе отсутствуют заголовки CORS. Chrome фактически получал ответ, но не позволял отображать ответ в представлении сети.

person brain_bacon    schedule 13.02.2014
comment
Спасибо - вы помогли мне решить мою собственную проблему. У меня были такие же симптомы. В моем случае я использовал шлюз Amazon API и вызывал его из AngularJS из Chrome. Мне не хватало параметра, как предлагает @tacticurv, но Chrome подразумевал, что он никогда не делал POST из-за CORS, когда запрос OPTIONS явно удался. Еще одна проблема, которую я обнаружил, заключалась в том, что полезная кнопка включения CORS шлюза API не выполняет полную работу. Он добавлял заголовки только к ответам 200 OK и пропускал их из ответов 400 и 500 ошибок. Затем эти ошибки были пропущены инспектором хрома! - person charltones; 19.01.2016
comment
@charltones На самом деле, с тех пор как я опубликовал этот ответ, я использовал chrome://net-internals/#events для обнаружения подобных ошибок вместо использования Firefox. Просто полезно знать на будущее. На самом деле я отправил ошибку в Chromium, и она была исправлена ​​на некоторое время, но я думаю, что они вернули ее. code.google.com/p/chromium/issues/detail?id= 343707 - person brain_bacon; 19.01.2016

CROS необходимо разрешить со стороны сервера.

Создайте фильтры в соответствии с требованиями, чтобы разрешить доступ и добавить фильтры в web.xml.

Пример использования пружины:

Класс фильтра:

@Component
public class SimpleFilter implements Filter {

@Override
public void init(FilterConfig arg0) throws ServletException {}

@Override
public void doFilter(ServletRequest req, ServletResponse resp,
                     FilterChain chain) throws IOException, ServletException {

    HttpServletResponse response=(HttpServletResponse) resp;

    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with");

    chain.doFilter(req, resp);
}

@Override
public void destroy() {}

}

Веб.xml:

<filter>
    <filter-name>simpleCORSFilter</filter-name>
    <filter-class>
        com.abc.web.controller.general.SimpleFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>simpleCORSFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
person nkharche    schedule 20.06.2015

Я только сегодня столкнулся с этой проблемой. Оказалось, что ошибка на сервере (исключение с нулевым указателем) приводила к сбою при создании ответа, но все равно генерировала код состояния HTTP 200. Из-за кода состояния 200 Chrome ожидал допустимого ответа. Первое, что сделал Chrome, это поискал заголовок «Access-Control-Allow-Origin», но не нашел. Затем Chrome отменил запрос, и Angular выдал мне ошибку. Ошибка во время обработки POST-запроса является причиной того, что OPTIONS завершатся успешно, но POST завершится ошибкой.

Короче говоря, если вы видите эту ошибку, возможно, ваш сервер вообще не вернул никаких заголовков в ответ на запрос POST.

person David Hansen    schedule 31.01.2014
comment
По сути, это была проблема, с которой я столкнулся - спасибо за внимание. - person Eamonn Gahan; 25.11.2014

Это также может произойти, когда ваши параметры неверны в запросе. В моем случае я работал с API, который отправил мне сообщение

«В запрошенном ресурсе отсутствует заголовок« Access-Control-Allow-Origin ». Следовательно, «нулевой» источник не является разрешенным доступом. В ответе был код состояния HTTP 401».

когда я отправляю неправильное имя пользователя или пароль с запросом POST для входа в систему.

person tacticurv    schedule 26.09.2015

Вместо $http.get('abc/xyz/getSomething') попробуйте использовать $http.jsonp('abc/xyz/ получить что-то')

     return{
            getList:function(){
                return $http.jsonp('http://localhost:8080/getNames');
            }
        }
person Indranil Acharya    schedule 30.03.2016

Если у вас, ребята, возникла эта проблема в Sailes.js, просто установите свой cors.js, чтобы включить авторизацию в качестве разрешенного заголовка.

/***************************************************************************
  *                                                                          *
  * Which headers should be allowed for CORS requests? This is only used in  *
  * response to preflight requests.                                          *
  *                                                                          *
  ***************************************************************************/

  headers: 'Authorization' // this line here

person Umar Rasydan    schedule 17.11.2015