сбои для поддоменов - PullRequest
3 голосов
/ 17 апреля 2019

CORS не работает должным образом для домена и субдомена. У меня есть один сервер NodeJS, размещенный на https://api.example.com У меня два клиента ReactJS

Клиент 1. https://example.com

Клиент 2. https://subdomain.example.com

Я настроил Клиента 1 на принудительное использование www, чтобы для Клиента 1 использовался один источник Когда я открываю Clien1, это прекрасно работает. Когда я открываю Client2, я получаю сообщение об ошибке

Доступ к XMLHttpRequest по адресу https://api.example.com/someAPI' от источника 'https://subdomain.example.com' заблокирован политикой CORS: заголовок' Access-Control-Allow-Origin 'имеет значение' https://www.example.com' не равный указанному источнику

Когда я нажимаю Ctrl + F5, тогда он работает нормально, но после этого, если я обновляю Client1, то появляется ошибка Client1

Доступ к XMLHttpRequest в 'https://api.example.com/someAPI' от источника' https://www.example.com' заблокирован политикой CORS: заголовок 'Access-Control-Allow-Origin' имеет значение 'https://subdomain.example.com' это не равно указанному источнику.

Теперь, когда я нажимаю Ctrl + F5 на Client1, он работает нормально, но та же самая ошибка идет на Client2.

Мой сервер nodeJS настроен следующим образом

var whitelist = ['https://www.example.com', 'https://subdomain.example.com'];
    getCorsCoptions(req, callback) {
    var getOriginValue = () => {
      if (whitelist.indexOf(req.header('origin')) !== -1) {
        return true;
      } else {
        log.error(__filename, 'Not allowed by CORS', origin);
        return false;
      }
    }
    var corsOptions = {
      origin: getOriginValue(),
      methods: ['GET', 'POST'],
      credentials: true,
      preflightContinue: false,,
      allowedHeaders:["Content-Type","X-Requested-With","X-HTTP-Method-Override","Accept"]
    }
    callback(null, corsOptions)
  }

app.use('*', cors(this.getCorsCoptions));
app.options('*', cors(this.getCorsCoptions));

Я использую axios на сторонах React Client следующим образом

get(url: string) {
    return Axios.get(url, {
      withCredentials: true
    }).then((res: any) => {
      if (res) {
        return res.data;
      }
      return {};
    });
}

post(url: string, data: any) {
    let requestHeaders = { 'Content-Type': 'application/json' };
    return Axios.post(url, data, {
      headers: requestHeaders
      , withCredentials: true
    }).then((res: any) => {
      if (res) {
        return res.data;
      }
      return {};
    });
}

Ответы [ 3 ]

0 голосов
/ 01 мая 2019

Это потому, что вы вызываете свою функцию, вам просто нужно передать ее промежуточному программному обеспечению

var corsOptions = {
      origin: getOriginValue, // Not origin: getOriginValue()<-no parens,
      methods: ['GET', 'POST'],
      credentials: true,
      preflightContinue: false,,
      allowedHeaders:["Content-Type","X-Requested-With","X-HTTP-Method-Override","Accept"]
    }
0 голосов
/ 21 мая 2019

Я нашел решение этой проблемы. Браузер кешировал происхождение. Решил эту проблему, добавив следующий заголовок в ответ

Cache-Control: no-store,no-cache,must-revalidate

Я также добавил Vary: Origin, но я думаю, что это не решило проблему Я управлял cors следующим образом

var whitelist = ['https://www.example.com', 'https://subdomain.example.com'];
router.all("*", (req, res, next) => {
    var origin = req.headers.origin;
    if (whitelist.indexOf(origin) != -1) {
      res.header("Access-Control-Allow-Origin", origin);
    }
    res.header("Access-Control-Allow-Headers", ["Content-Type","X-Requested-With","X-HTTP-Method-Override","Accept"]);
    res.header("Access-Control-Allow-Credentials", true);
    res.header("Access-Control-Allow-Methods", "GET,POST");
    res.header("Cache-Control", "no-store,no-cache,must-revalidate");
    res.header("Vary", "Origin");
    if (req.method === "OPTIONS") {
    res.status(200).send("");
      return;
    }
    next();
});

где маршрутизатор экспресс. Маршрутизатор ()

Я надеюсь, что кто-то найдет это полезным.

0 голосов
/ 25 апреля 2019

Кажется, вы используете экспресс. Основываясь на их документах, вы можете установить источник в массив строк или RegExp, который должен разрешать источники, которые вы хотите.

origin: Конфигурирует заголовок CORS Access-Control-Allow-Origin. Возможные значения:

  • Array - установить источник в массив действительных источников. Каждый источник может быть String или RegExp. Например ["http://example1.com", /.example2.com$/] примет любой запрос из «http://example1.com” или из субдомена« example2.com ».

Исходя из этого, обновление getOriginValue() до следующего может работать для вас:

var getOriginValue = () => {
  if (whitelist.indexOf(req.header('origin')) !== -1) {
    return whitelist; // Return array of strings
  } else {
    log.error(__filename, 'Not allowed by CORS', origin);
    return false;
  }
}
...