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

Я застрял в этой проблеме 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 cannot load http://stackoverflow.com/. Origin http://localhost is not allowed by Access-Control-Allow-Origin.

Я подозреваю, что проблема в клиенте script, а не настройка сервера...

Ответ 1

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

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

Ответ 2

Согласно ответу @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:*/*

Ответ 3

Реальная проблема заключается в том, что если мы установим -Allow- для всего запроса (OPTIONS & POST), Chrome отменит его. Следующий код работает для меня с POST в LocalHost с 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);
} 
?>

Ответ 4

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

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

Ответ 5

Сегодня столкнулся с этим в Chrome и обнаружил, что переключение на Safari и выбор " Disable Cross-Origin Restrictions по всему Disable Cross-Origin Restrictions в меню " Develop позволили мне выполнить сторонний API-вызов с localhost.

Ответ 6

Я был полон кошмара с cors на днях, поэтому я изменил свою парадигму программирования.

для моего веб-приложения, которое я сейчас разрабатываю, в конечном итоге я развертываю в производство, в этом случае я использую Heroku. Для работы на стороне сервера, например http, я использую Postman для проверки всех http-маршрутов, почтальон не блокируется cors.

После того, как мои модульные тесты выполнены и проверены, я развертываю сервер в Heroku и затем работаю на клиенте. таким образом, клиент делает запросы к серверу, который находится в другом месте и не получает Cors.