向https:www.google.com的获取请求失败(显然),因为出现了CORS。

7
我的用例:我正在尝试向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);
    }

附言:我知道没有办法禁用同源策略或强制其他站点发送允许所有来源标头。但是可以通过使用cors代理来绕过此限制。 我想知道是否可以使用Google.com或类似的易于获得的站点来验证我的连接方式,如果不能,那么从获取连接信息的角度来看,是否有其他方法来处理它们。


3
有些相关,我建议您使用http://connectivitycheck.gstatic.com/generate_204。这也是由Google创建的,但用于检查您是否有有效的连接。请确保与状态码204进行比较。获取google.com将返回不必要的数据并需要90毫秒,而gstatic则不返回任何内容且仅需30毫秒。 - Zun
如果你能找到任何公开可用的启用CORS的Google“endpoint”,并且你想假设它与Google主页面具有相同的“可靠性”,那么你可以使用它。否则,你所能做的不多,因为使用CORS代理的一般“解决方法”当然会首先将大部分“可靠性”响应放在代理上。 - 04FS
@Zun,谢谢老兄,我现在就去看看。 - tariq
@04FS 是的,你说得对,谢谢。 - tariq
@Zun,gstatic 也出现了相同的跨域错误! - tariq
5个回答

3

您可以使用init对象为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请求,因为您不需要使用响应正文。

1
那样做没有帮助。no-cors 只是告诉浏览器阻止 JavaScript 代码查看响应正文和标头的内容。 除了在本地使用某些扩展或标志等方式之外,绝对不能从客户端禁用同源策略。 - tariq
@tariq 当然你无法访问响应,但它不会因为跨域而失败。只有在你未连接到网络时才会被拒绝。 - ikarasz
@tariq,它在我的网站上可以运行,你应该试一下。 - ikarasz
有趣。我之前也尝试过,但那时候它没有起作用。现在它工作了!让我再确认一下,然后就会接受你的答案。 - tariq
1
对于我狭窄的使用情况,只需获取连接状态或成功状态代码即可+1,并接受答案。我不需要响应头或响应正文。如果是这种情况,那么 no-cors 将没有任何帮助。 - tariq

0

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

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

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

请注意,此存储库未得到适当维护

github链接在这里


0

作为替代方案,您可以使用已禁用CORS的CDN链接。例如:

fetch("https://code.jquery.com/jquery-2.2.4.min.js")
    .then(x => x.text())
    .then(x => console.log(x.substring(4, 15) === "jQuery v2.2"))


-1

您可以使用https://developer.mozilla.org/zh-CN/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)
  })


-2
我想知道是否可以使用google.com或类似的易于获取的网站来验证我的连接性,如果不行,那么从仅获得连接信息的角度来看,是否有其他处理方法。

不,没有其他方式。

正如您已经确定的那样,您需要CORS权限才能这样做。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接