Смертельна CORS, коли http: // localhost є початком


186

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

Я бачу на панелі Мережа Chrome -> заголовки відповідей:

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.

Я підозрюю, що це проблема в клієнтському скрипті, а не в налаштуваннях сервера ...


44
Ні, stackoverflow.com повинен встановити цей заголовок, а не ви. : х. Який же сенс матиме політика щодо походження в іншому випадку.
Есаїлія

3
Спробуйте отримати доступ до встановленого сервера, а не переповнювати стек. ;)
Нек

ДОХ! Чи є спосіб сказати 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) або запустити хром із --disable-web-securityпрапором (якщо вважати, що ви просто тестуєте).


24
@greensuisse - це не публікація для localhost. Це проблема розміщення від localhost.
Cheeso

9
Ця помилка недійсна (і позначена як така - crbug.com/67743#c17 ). Коментар Esailija правильний, додавання цих заголовків до localhost не надасть магічного доступу до всіх інших сайтів. Це віддалений сайт, який потрібно обслуговувати з цими заголовками.
Rob W

22
Щойно провів 2 години на тестуванні на Chrome, щоб зрозуміти, що він прекрасно працює у Firefox ..Grrrr...
FloatingRock

11
Інший варіант: відредагуйте свій хост-файл так, щоб локальний. [Mysite] .com вказує на 127.0.0.1, а потім дозволити файл CORS дозволити *. [Mysite] .com
Tom

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-адреси localhost із наступним фільтром URL-адрес

*://localhost:*/*

14
Якщо ви прочитаєте посилання @beau на проблему, ви побачите, що Chrome 100% підтримує запити між походженнями та з Localhost. Випуск було закрито в 2014 році, оскільки його не вдалося відтворити. Решта шуму в цій темі - це люди з неправильно налаштованими серверами без походження (як це стосується оригінального запитання тут).
Моломбі

1
Працював як шарм для мене на хромі
Aakash


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);
} 
?>

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.


я додав це розширення до моєї Опери, і тепер його розпалось. я ніколи не можу сказати, коли його вмикати та вимикати, тому я використовую firefox для роботи. та опера для розвитку. Костюм в Google не подобається, і інших речей теж немає.
Maddocks

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
 }
}

У разі кутового я обслуговую цю конфігурацію:

$ 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.