在一个固有的环境中,需要让用户点击后台配置的不固定链接后,不非正常跳出固有业务系统,所以需要判断用户点击的 URL(内容)是否有效。那么如何判断一个 URL 是否有效呢?
背景
实体为终端机器,在 APP Webview 中加载 Web 单页面应用(SPA)。机器理论上可以24小时不间断工作(不关机),用户无法手动输入 URL。首页部分广告链接由后台管理,用户点击链接跳转相应页面。
问题
在用户点击链接(可能跨域)的时候,无效链接可能导致跳出业务系统,由于没有系统导航,则无法再返回原有业务系统,造成系统整体瘫痪。
定义
- 有效链接:HTTP 请求 URL,相应内容可正常加载(一般为
200),此外均为不正常 - 无效链接:HTTP 请求 URL,相应状态码以 4 或 5 开头的错误类型(如
404),详细参考 HTTP 状态码
需求
在用户点击链接后,若是有效链接则执行正常路由跳转,否则友好提示错误原因,或者进行容错处理。
尝试解决
AJAX 请求
- 同源:可通过 AJAX 返回状态来判断
- 不同源:请求被浏览器阻止,返回 404,无法获取真实返回结果
JSONP 方式
JSONP 原理是采用动态添加 script 方式协同传输数据,因此需要服务器协助,返回约定格式数据,再作为脚本执行。
由于 URL 内容为 HTML 文档,不是 JSONP 格式数据,无法采用。
iframe 标签
iframe 标签本身就用于嵌入文档,而且支持跨域加载
可是问题来了,无法区分其加载内容结果状态,内容为 404 不存在时,其响应状态也为 200,都会触发 onload 事件,无 onerror 事件(暂有疑问)
不是办法的办法:通过查找内容文档的标题是否包含 404 等来判断结果
最终方案
<link> 标签
<link> 标签一般用于 CSS 样式表的加载,也可以可用于 预加载 使用(rel="prefetch")
1 | <link rel="prefetch" href="http://foo.com" > |
HTMLLinkElement 对象提供了 onload 和 onerror 事件,可分别对应加载成功和加载失败的事件处理
解决方案部分代码如下:
1 | function checkValidURL (url, success, fail) { |
但是跨域 URL 可能依旧会有问题:
1 | Refused to prefetch content from 'https://www.foo.com/xxx' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'prefetch-src' was not explicitly set, so 'default-src' is used as a fallback. |
另见:Preloading content with rel="preload"
其他方案
服务器提供 API,前端传入 URL,后端进行判断,返回结果。
未完待续
若您有这个需求,或者对这个问题感兴趣,希望能参与交流


