【问题标题】:Fetch request to https:www.google.com fails (obviously) with CORS使用 CORS 获取对 https:www.google.com 的请求(显然)失败
【发布时间】:2019-10-23 16:45:33
【问题描述】:

我的用例:我正在尝试向https://www.google.com 发出一个简单的 fetch GET 请求以检查互联网连接。我需要检查响应代码,并据此确定用户是否有互联网连接。现在,虽然我可以在开发人员工具中看到 200 代码(没有响应标头或响应),但 fetch 始终无法进入 fetch 调用的错误处理程序,并且控制台会标记 CORS 错误。

我确实理解,因为我正在发出跨域请求,所以这应该会导致 CORS 错误。

我想知道如何才能让我的连接代码正常工作。我显然无法更改 google.com 的响应标头。为此使用 google.com 的原因是因为它的可靠性,就像我们在浏览器中点击 google.com 主要是为了检查互联网是否正常工作:D

我的代码:

networkMonitor: () => {
      const headers = new Headers();
      headers.append('Cache-Control', 'no-cache');
      const timerId = setInterval(() => {
        fetch('https://www.google.com')
          .then((response) => {
            if (response.status != 200) {
               // Yay ! connected
            }
          }, (err) => {
            console.log("error: " + err); // (currently fetch failed)
          })
      }, 5000);
    }

P.S:我知道没有办法禁用同源策略或强制其他站点发送允许所有源头。这可以通过使用 cors 代理绕过。 我想知道是否可以通过我的方式使用 google.com 或类似的现成网站来验证连接,如果没有,那么从仅获取连接信息的角度来看,是否有其他方法来处理它们。

【问题讨论】:

  • 有点相关,建议你改用http://connectivitycheck.gstatic.com/generate_204。也由 Google 制作,但创建是为了检查您是否有有效的连接。确保与状态码 204 进行比较。获取 google.com 会返回不必要的数据并且需要 90 毫秒,而 gstatic 什么也不返回并且需要 30 毫秒
  • 如果您可以找到任何支持 CORS 的公开可用的 Google“端点”,并且您想假设它与 Google 主页具有相同的“可靠性”,那么您可以使用它。否则,您无能为力 - 因为使用 CORS 代理的一般“解决方法”当然会将大部分“可靠性”响应放在代理上。
  • @Zun ,谢谢伙计现在要调查一下。
  • @04FS 是的,谢谢。
  • @Zun 与 gstatic 相同的 cors 错误!

标签: javascript cors fetch


【解决方案1】:

您可以使用其 init 对象将一些 parameters 添加到您的 fetch 请求中。 将 mode 属性设置为 no-cors 后,您可以向 URL 发送 GET 和 HEAD 请求,但无法访问响应。

networkMonitor: () => {
  const headers = new Headers();
  headers.append('Cache-Control', 'no-cache');
  const timerId = setInterval(() => {
    fetch('https://www.google.com', {
      mode: 'no-cors'
    })
    .then((response) => {
      if (response.status != 200) {
        console.log('Yay ! connected')
      }
    }, (err) => {
      console.log('error: ' + err); 
  }, 5000);
}

另外,我会考虑发送 HEAD 请求,因为您不想使用响应正文

【讨论】:

  • 那无济于事。 no-cors 只是告诉浏览器阻止 javascript 代码查看响应正文和标头的内容。除非在本地使用某些扩展或标志等,否则绝不可以从客户端禁用同源策略。
  • @tariq 当然你不能访问响应,但它不会因为 cors 而失败。仅当您未连接到网络时才会拒绝。
  • @tariq 可以在我自己的网站上使用,你应该试试
  • 有趣。我之前也尝试过使用它,但当时没有工作。它现在正在工作!让我再确认一下,然后会接受你的回答。
  • +1,对于我仅成功获取连接状态或状态代码的狭窄用例,答案已被接受。我不需要响应标头或响应正文。如果是这样的话,那么 no-cors 就没有任何帮助了。
【解决方案2】:

您可以使用https://developer.mozilla.org/en-US/docs/Web/API/Request/mode 将模式设置为“no-cors”。这对我有用。使用 HEAD 请求而不是 GET 来节省带宽也可能就足够了。

请注意“no-cors”文档中的这句话:

JavaScript 可能无法访问结果响应的任何属性

在我的测试中,响应对象只是空的。对 response.status 或 response.ok 的检查失败。

fetch('https://www.google.com', {
    method: 'HEAD',
    mode: 'no-cors'
  })
  .then((response) => {
    console.log("connected");
  }, (err) => {
    console.log("error: " + err); // (currently fetch failed)
  })

【讨论】:

    【解决方案3】:

    您可以使用offline.js 执行此任务。它有不同的方法来检查连接状态。

    Offline.check():检查当前连接状态。

    Offline.state:连接“up”或“down”的当前状态

    请注意,此 repo 未正确维护

    github链接是here

    【讨论】:

      【解决方案4】:

      我想知道是否可以使用 google.com 或类似的现成网站以我的方式验证连接性,如果不能,那么从刚刚获取的角度来看,是否有其他方法可以处理它们连接信息。

      不,没有。

      正如您已经确定的那样,您需要 CORS 权限才能执行此操作。

      【讨论】:

        猜你喜欢
        • 2020-07-08
        • 2015-04-03
        • 2018-03-06
        • 2021-05-22
        • 1970-01-01
        • 2022-01-23
        • 2021-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多