Смертельный CORS, когда http: // localhost является источником

186

Я застрял с этой проблемой CORS, хотя я установил сервер (nginx / node.js) с соответствующими заголовками.

Я вижу на панели Chrome Network -> Заголовки ответа:

Access-Control-Allow-Origin:http://localhost

который должен сделать свое дело.

Вот код, который я сейчас использую для тестирования:

var xhr = new XMLHttpRequest();
xhr.onload = function() {
   console.log('xhr loaded');
};
xhr.open('GET', 'http://stackoverflow.com/');
xhr.send();

я получил

XMLHttpRequest не может загрузить http://stackoverflow.com/ . Источник http: // localhost не разрешен Access-Control-Allow-Origin.

Я подозреваю, что это проблема в клиентском скрипте, а не в конфигурации сервера ...

whadar
источник
44
Нет, stackoverflow.com должен устанавливать этот заголовок, а не вы. :Икс. В чем же смысл политики происхождения в противном случае.
Esailija
3
Попробуйте получить доступ к серверу, который вы настроили, не переполняйте стек. ;)
Nek
DOH! Есть ли способ сказать Chrome (или другой браузер), чтобы получить ресурс, даже если заголовок отсутствует, когда мой источник является localhost?
whadar
Запускаю свои коды в Chrome (20.0.1132.57, Windows 7), работает отлично.
imwilsonxu
1
Если вы используете localhost с портом, этот ответ сработал для меня serverfault.com/a/673551/238261 .
Нелу

Ответы:

230

Chrome не поддерживает localhost для запросов CORS (ошибка, открытая в 2010 году и помеченная как WontFix в 2014 году).

Чтобы обойти это, вы можете использовать домен, подобный lvh.me(который указывает на 127.0.0.1, как localhost) или запустить chrome с --disable-web-securityфлагом (при условии, что вы просто тестируете).

кавалер
источник
24
@greensuisse - это не публикация на localhost. Это сообщение от localhost, что является проблемой.
Cheeso
9
Эта ошибка недействительна (и была помечена как таковая - crbug.com/67743#c17 ). Комментарий Esailija верен, добавление этих заголовков к localhost волшебным образом не даст вам доступ ко всем остальным сайтам. Это удаленный сайт, который должен обслуживаться этими заголовками.
Роб W
22
Просто потратил 2 часа на тестирование Chrome, чтобы понять, что он отлично работает в Firefox ..Grrrr...
FloatingRock
11
. Другой вариант: изменить ваш файл хостов , так что местные [MySITE] .com указывает на 127.0.0.1, а затем сделать свой файл CORS позволит * [MySite] .com.
Том
6
Я столкнулся с той же проблемой с FireFox. Я мог сделать это только на Edge! Хороший пост, фантастический! :)
Луис Гувея
54

Согласно ответу @ Beau, Chrome не поддерживает локальные CORS-запросы, и вряд ли что-то изменится в этом направлении.

Я использую расширение Allow-Control-Allow-Origin: * Chrome, чтобы обойти эту проблему. Расширение добавит необходимые заголовки HTTP для CORS:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: "GET, PUT, POST, DELETE, HEAD, OPTIONS"
Access-Control-Expose-Headers: <you can add values here>

Исходный код опубликован на Github .

Обратите внимание, что расширение фильтрует все URL по умолчанию. Это может сломать некоторые веб-сайты (например, Dropbox). Я изменил его, чтобы фильтровать только локальные URL со следующим фильтром URL

*://localhost:*/*
Hanxue
источник
14
Если вы прочитаете ссылку @beau на проблему, вы увидите, что Chrome 100% поддерживает запросы из разных источников на локальный хост и с него. Выпуск был закрыт в 2014 году, поскольку его невозможно воспроизвести. Остальная часть шума в этом потоке - это люди с неправильно настроенными серверами, не являющимися источниками (как в оригинальном вопросе здесь).
Моломби
1
Работал, как обаяние для меня на хром
Аакаш Сахай
3
Это расширение не работает , Access-Control-Allow-Credentials: trueпоскольку он устанавливает Access-Control-Allow-Originдля *и имеющих как trueи *блокируется браузерами. Если вы используете учетные данные true, вы должны использовать источник без подстановочных знаков. Я рекомендую Moesif Origins и CORS Changer Extension, которые позволяют менять заголовки так, как вы хотите.
Самуил
Возможно, я делаю что-то не так, но это расширение больше не работает для меня.
Джеймс Паркер
19

Реальная проблема в том, что если мы установим -Allow-для всех запрос ( OPTIONS& POST), Chrome отменит его. Следующий код работает для меня с POSTLocalHost с Chrome

<?php
if (isset($_SERVER['HTTP_ORIGIN'])) {
    //header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
    header("Access-Control-Allow-Origin: *");
    header('Access-Control-Allow-Credentials: true');    
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 
}   
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
        header("Access-Control-Allow-Headers:{$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

    exit(0);
} 
?>
greensuisse
источник
15
OP использует nginx / node.js. Не PHP
code_monk
4

Chrome будет делать запросы с CORS от localhost источника просто отлично. Это не проблема с Chrome.

Причина, по которой вы не можете загрузить, http://stackoverflow.comзаключается в том, что Access-Control-Allow-Originзаголовки не позволяют вам localhostотправиться.

штифтик
источник
2

Быстрое и грязное исправление расширения Chrome:

Moesif Orign & CORS Changer

Тем не менее, Chrome поддерживает перекрестные запросы от localhost. Не забудьте добавить заголовок Access-Control-Allow-Originдля localhost.

kaleazy
источник
я добавил это расширение в мою оперу, и теперь его F'up. Я никогда не могу сказать, когда он включен и выключен, поэтому я использую Firefox для работы. и опера для развития. Google костюм не нравится, и другие вещи тоже не нравятся.
Мэддокс
1

У меня не работает ни одно из расширений, поэтому я установил простой локальный прокси. В моем случае https://www.npmjs.com/package/local-cors-proxy Это 2-минутная установка:

(с их сайта)

npm install -g local-cors-proxy

Конечная точка API, которую мы хотим запросить, имеет проблемы с CORS: https://www.yourdomain.ie/movies/list

Запустить прокси: lcp --proxyUrl https://www.yourdomain.ie

Затем в вашем клиентском коде новая конечная точка API: http://localhost:8010/proxy/movies/list

Для меня это сработало: ваше приложение вызывает прокси, который вызывает сервер. Ноль проблем CORS.

Даниэль П
источник
0

Я решил не трогать заголовки и вместо этого сделать переадресацию на стороне сервера, и это просыпается как очарование.

Пример ниже относится к текущей версии Angular (в настоящее время 9) и, возможно, к любой другой платформе, использующей веб-пакеты DevServer. Но я думаю, что тот же принцип будет работать на других серверах.

Поэтому я использую следующую конфигурацию в файле proxy.conf.json :

{
  "/api": {
    "target": "http://localhost:3000",
    "pathRewrite": {"^/api" : ""},
   "secure": false
 }
}

В случае Angular я работаю с такой конфигурацией:

$ ng serve -o --proxy-config=proxy.conf.json

Я предпочитаю использовать прокси в команде serve, но вы также можете поместить эту конфигурацию в angular.json следующим образом:

"architect": {
  "serve": {
    "builder": "@angular-devkit/build-angular:dev-server",
    "options": {
      "browserTarget": "your-application-name:build",
      "proxyConfig": "src/proxy.conf.json"
    },

Смотрите также:

https://www.techiediaries.com/fix-cors-with-angular-cli-proxy-configuration/

https://webpack.js.org/configuration/dev-server/#devserverproxy

Юрий Синицон
источник