Я не получаю "Access-Control-Allow-Origin" после бесчисленного количества раз, когда мой скрипт работает

Я строю небольшой API на фоне сервера из PHP. Я использую поддомен api.website.com. Просто для отладки у меня это в верхней части индекса моего index.php в поддомене

header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Credentials: true');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE");

а для моего javascript кода на основном сайте есть.

$.ajax({
  xhrFields: {
    withCredentials: true
  },
  headers: {
    "X-My-Custom-Header": "some value"
  },
  url: 'https://api.website.com/',
  type: 'GET',
  processData: false,
  contentType: "application/json",
  dataType: 'json',
  data: '{}',
  success: function(r) {
    console.log(r);
  },
  error: function(r) {}
});

Все это работало нормально до вчерашнего дня, сегодня, когда я начал работать над этим, я получил это.

Ответ на запрос предварительной проверки не проходит проверку контроля доступа: в запрошенном ресурсе отсутствует заголовок "Access-Control-Allow-Origin". Происхождение " https://website.com/" поэтому не допускается

Я нахожу странным, что все это работало вчера, и теперь я не знаю, что происходит.

3 ответа

Решение

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

Вы не можете использовать withCredentials и подстановочный знак происхождения. В противном случае это риск безопасности. Смотрите: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin

Хорошо, я не знаю, как я решил проблему, но я предполагаю, что, как сказано выше, в заголовке кеша. Я перезапускаю ssl с cloudflare, потому что он любит кэшировать все. Теперь, чтобы заставить это работать, я должен удалить эти две вещи из JavaScript.

headers: {"X-My-Custom-Header": "some value"},

а также

contentType: "application/json",

из всех моих вызовов AJAX.

как я упоминал подстановочный знак, который я использовал только для целей тестирования, просто чтобы посмотреть, была ли проблема в моем динамическом php-коде. К счастью, не было.

function cors() {

$domain = ltrim($_SERVER['HTTP_HOST'], "api.");
$origin = $_SERVER['HTTP_ORIGIN'];


if (preg_match("/^http[s]?[:]\/\/(w{3})?[.a-zA-Z ]*".$domain."$/i", $origin)) {
    header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Max-Age: 86400');    // cache for 1 day
}

// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
        // may also be using PUT, PATCH, HEAD etc
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE");         

    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
        header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
    exit(0);
}
header('Content-Type: application/json');
header('Accept: application/json');
}

это вызывается в начале cors(); не вызывать перекрестное загрязнение коллектора и континента.

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

Обновление: Я думал, что cloudflare портит заголовки https://support.cloudflare.com/hc/en-us/articles/200308847-Does-Cloudflare-support-Cross-origin-resource-sharing-CORS- Но похоже это могут быть не они, даже если они очистили кеш, которому они помогли. Тогда я застрял на другой проблеме, POST и GET работали просто отлично, но не такие вещи, как DELETE и OPTIONS. Поэтому после анализа и исследования я обнаружил, что header() в PHP не работал. Оказывается, что заголовки PHP не установлены с помощью litespeed (но работают с apache) из-за litespeed.

Я должен иметь заголовки на.htaccess как временное исправление. Я имею в виду, что заголовки PHP работают, но по какой-то странной причине то, что я вижу в заголовках для почтальонов, не согласовано в AJAX.

Другие вопросы по тегам