使用 JS Fetch 测试网站连通性
在浏览器或 Node.js 中使用 JavaScript 的 Fetch 测试网站连通性
自己有在浏览器测试网站连通性的需求,最后使用 Fetch 实现了,就在这里分享一下中间遇到的坑和最后的解决方案,不想看前面废话可以直接跳转文末查看代码
XHR
最开始打算直接用 XMLHttpRequest
解决,但是浏览器遇到了跨域拦截(CORS 失败)
- js
1 | let xhr = new XMLHttpRequest(); |
出现 Access to XMLHttpRequest at (url) from origin (src) has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
报错,是因为待测的目标 URL(在这个示例中是 https://www.google.com )没有允许浏览器读取响应信息
正常情况下,xhr.status
应该会给我们响应的状态码,浏览器此时已经成功收到了 302 重定向的响应,但是 xhr 请求出现了 CORS 错误,再尝试获取这个状态码只能得到 0
也就是说,无论是否可以访问待测网站,xhr.status
都只会返回 0
在浏览器中,XHR 请求都受到 CORS 策略的限制,而 XHR 也无法使用 no-cors
模式来绕过这个限制,这个时候,我们就需要使用 Fetch
了
Fetch
Fetch
是 XMLHttpRequest
更现代的替代品,是 ES6(ECMAScript 2015)的东西(也就是说不支持 IE)
除了过时的 Internet Explorer 和 Windows Script Host,基本所有可以执行 JS 的地方都能使用 Fetch
,你甚至可以在 Node.js 中使用它
先用 Fetch
重写下文章开头的代码
- js
1 | fetch("https://www.google.com", { |
同样会获得 CORS 错误,提示 Failed to fetch
,注意看,这个错误属于 TypeError
但是我们可以让 Fetch
使用 no-cors
,来绕过这个 CORS 限制!
改进一下代码,然后观察 Fetch
出现的 Error:
- js
1 | var request = fetch("https://www.google.com", { |
执行这段代码,我们会得到 Error: SyntaxError: Unexpected end of input
为什么会得到 SyntaxError
呢?因为 no-cors 会阻止浏览器获取响应的内容
但实际上,如果我们得到了 SyntaxError
,则说明这个请求已经发送成功,并且接收到了响应
让我们将测试 URL 改为一个不存在的地址,再试一遍:
- js
1 | var request = fetch("https://this.domain.does.not.exist", { |
执行代码,我们会得到 Error: TypeError: Failed to fetch
也就是说,带上 no-cors
之后,虽然请求成功也会报错,但是出现的是另一个报错
- 请求成功:
SyntaxError
- 请求失败:
TypeError
接下来,对着不同错误做不同处理,就可以检测啦
解决方案
直接放代码:
- js
1 | var request = fetch("https://www.google.com", { |
如果请求成功,控制台输出 Google OK,如果失败,输出 Google Failed
这段代码可以在浏览器里面跑,也可以使用 Node.js 运行