【问题标题】:Cant enable CORS on the server side NodeJS无法在服务器端 NodeJS 上启用 CORS
【发布时间】:2020-07-25 22:23:25
【问题描述】:

我无法在服务器端启用CORS。我的前端和后端服务器有不同的端口。以下是服务器端的实现方式:

http
  .createServer(function (req, res) {
    // .. Here you can create your data response in a JSON format
    // const { headers, method, url } = req;
    // let body = [];
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Request-Method', '*');
    res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
    res.setHeader('Access-Control-Allow-Headers', '*');
    if (req.method === 'OPTIONS') {
      res.writeHead(200);
      res.end();
      return;
    }

    // const responseBody = { headers, method, url, body: JSON.stringify(data) };

    response.write('{asd: 123}'); // Write out the default response
    res.end(); //end the response
  })
  .listen(port);

我从前端调用fetch 函数,如下所示:

fetch('http://localhost:3035', {
      method: 'POST',
      mode: 'same-origin', // no-cors, *cors, same-origin
      cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
      credentials: 'include', // include, *same-origin, omit
      headers: {
        'Content-Type': 'application/json',
        // 'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: JSON.stringify(line), // body data type must match "Content-Type" header
    })
      .then((response) => response.json())
      .then((data) => console.log(data))
      .catch((error) => console.log(error));

但仍然出现错误:

Security Error: Content at http://localhost:3030/ may not load data from http://localhost:3035/.

TypeError: "NetworkError when attempting to fetch resource."

【问题讨论】:

  • @CherryDT - 把它写下来作为答案
  • 您的默认响应不是有效的 json。也发送 POST 但只允许 GET

标签: javascript node.js http post server


【解决方案1】:

您通过设置mode: 'same-origin' 而不是默认的mode: 'cors' 在客户端明确不允许 CORS。

引用docs

same-origin — 如果向具有此模式设置的另一个源发出请求,则结果只是一个错误。您可以使用它来确保始终向您的来源发出请求。

由于http://localhost:3035/ 不同于http://localhost:3030/ 的另一个来源,因此结果正如设计的那样,“只是一个错误”。

将其设置为mode: 'cors' 或完全删除mode,因为无论如何cors 是默认值。


附带说明,Access-Control-Request-Method 是预检请求中的 request 标头,而不是响应标头。你应该删除它。


如 cmets 中所述:要使凭证请求生效,您不能使用允许的来源 *。如果此时您不想硬编码预期的来源,则可以通过始终返回当前请求的来源来避免此问题,使用res.setHeader('Access-Control-Allow-Origin', req.headers.origin)

【讨论】:

  • “设置原点”是什么意思?当您查看网络选项卡时,您会看到从 API 返回的哪些响应标头?
  • 如果您看到该错误,则表示您正在发出凭据请求。这意味着您的请求具有会话 cookie 或具有 Authentication 标头或具有 Authorization 标头。仅将 Access-Control-Allow-Credentials 发送回 true 还不够。关于凭据请求,您需要了解的一件事是,浏览器禁止此类请求的来源 * 并禁止来源列表(以 Access-Control-Allow-Origin 发送多个 url。唯一可行的是做res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3030')——注意不是3035
  • .. 对于一般情况,您应该这样做 res.setHeader('Access-Control-Allow-Origin', req.headers.origin) - @CherryDT 您可以在答案中包含此信息吗?
  • 哦。忘了提。如果您真的想要将 CORS 用于其预期用途 - 禁止其他网站使用您的 API - 您可以检查 req.headers.origin 并查看它是否与您的允许网站列表匹配:if (req.headers.origin.match(SOME_RULE) {res.setHeader('Access-Control-Allow-Origin', req.headers.origin)}跨度>
  • @ЯрославТерещук - 只需res.setHeader('Access-Control-Allow-Origin', req.headers.origin)
猜你喜欢
  • 1970-01-01
  • 2017-02-20
  • 2019-01-28
  • 2021-03-12
  • 2019-08-14
  • 2018-01-30
  • 2018-10-30
  • 2023-03-05
  • 1970-01-01
相关资源
最近更新 更多