子域的cors失败

时间:2019-04-17 13:31:28

标签: node.js reactjs express cors axios

CORS在域和子域中无法正常工作。 我有一台NodeJS服务器托管在 https://api.example.com 我有两个ReactJS客户端

客户端1. https://example.com

客户端2。 https://subdomain.example.com

我已将客户端1配置为强制www,以便客户端1使用单个来源。 当我打开Clien1时,效果很好。 当我打开Client2时,出现错误

  

CORS策略已阻止从源“ https://api.example.com/someAPI”访问“ https://subdomain.example.com”处的XMLHttpRequest:“ Access-Control-Allow-Origin”标头的值为“ https://www.example.com” '不等于提供的来源

当我按Ctrl + F5时,它可以正常工作,但是之后如果刷新Client1,则错误发生在Client1

  

CORS策略已阻止从源“ https://api.example.com/someAPI”访问“ https://www.example.com”处的XMLHttpRequest:“ Access-Control-Allow-Origin”标头的值为“ https://subdomain.example.com” '不等于提供的原点。

现在,当我在Client1上按Ctrl + F5时,它可以正常工作,但相同的错误出现在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));

我正在React Client端使用axios,如下所示

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 :(得分:0)

好像您在使用快递。根据他们的文档,您可以将origin设置为字符串数组或RegExp,以允许您想要的起源。

  

起源:配置Access-Control-Allow-Origin CORS标头。   可能的值:

     
      
  • Array-将原点设置为有效原点的数组。   每个原点可以是一个字符串或一个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;
  }
}

答案 1 :(得分:0)

这是因为您正在调用函数,只需要将其传递给中间件

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

答案 2 :(得分:0)

我找到了解决此问题的方法。浏览器缓存源。 通过添加以下标头来解决此问题

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

表示路由器的路由器。Router()

我希望有人能对此有所帮助。