背景
最近在做公司内部的项目,测试在测试过程中发现接口请求完成之后没有带过相关的数据,随后打开控制台查看是否是接口问题,发现接口报如下的异常,状态码是 200,但返回的内容显示不出来,而且控制台是提前打开 Preserve log 的,理论上之前发送的请求是应该会有记录的,但结果确看不到 Response。
经过排查过后发现是对 Preserve log 的理解有偏差,由此引发了接下来的探索。
Preserve log 简介
To save requests across page loads, check the Preserve log checkbox on the Network panel. DevTools saves all requests until you disable Preserve log.
按照 Chrome 官方文档的介绍,Preserve log 如果勾选,在跨页面加载请求时,会保留之前的所有请求,目的是为了方便开发同学排查一些跨站请求是接口的一些问题,比如数据对比等。
但是官网没有写的是如果想要看到返回的 Response,你必须在页面跳转之前先提前点击查看该接口,才能在跳转之后看到之前的接口返回的信息,对于那些没有点击过的接口,在下一个页面中是查看不到返回的结果的,Response 看到的信息跟上图是类似的,都会有一个共同的报错“Failed to load response data”。
那是不是所有的浏览器都这样呢?还是只是 Chrome 一家是这种情况?接下来对 Preserve log 的兼容性做了一个分析。
Preserve log 兼容性
我们选取三个浏览器做样本,分别是 Chrome、Safari、Firefox。验证的步骤如下:
- 选取一个能从 A 网站跳转到 B 网站的页面
- 打开控制台,勾选 Preserve log 选项
- 刷新页面,找任意一个 A 页面的请求打开,其它的请求不点击
- 点击 A 网站 跳转到 B 网站的链接,在 B 网站查看之前 A 网站的请求数据
实验结果如下:
Chrome
在 Chrome 中,实验结果跟我们之前看到的是一样的,只会对点击的请求做保留,未点击的请求不会展示 Response。
Safari
在 Safari 中,Preserve log 的表现跟 Chrome 是一致的,只有点击之后的接口才会保留 Response,未点击的会展示“尝试载入资源时发生错误”,查看不了相应的结果,Safari 有个好处是,当跳转到 B 网站之后,控制台中 A 网站的请求都置灰了,会方便观察和操作。
Firefox
在 Firefox 中,如果勾选了 Persist Logs 之后,请求是会被完整的保留下来的,在下一个页面中能看到上一个页面完整的请求和返回的信息,说明 Firefox 是不受限制的。
Preserve log 为什么不会完整保留请求日志
通过以上的分析会发现,不同浏览器对保留日志的处理是不一样的。Chrome 这种处理方式在 issue 上也引发了广泛的讨论,而且还是一个历史悠久的 issue,总结下来大致观点分为两派。
反对方:
- NetWork 出现的错误很容易让别人误以为错误出现在服务端,引起误解
- 如果重定向发生的非常快,用户是很难去点击链接的,所以还得借助第三方工具帮助
- Preserve log 有歧义,明明是保留日志,但实际的结果确没有像 Charles 等工具一样完整的保留日志
赞同方(chromium 开发者):
- 这是“low overhead”的结果,Response 并不会传到 DevTools,除非用户想要查看并点击它,目的是为了避免歪曲测量结果
- 如果将所有的 Response 都保留在 DevTools,则会增加很多的不必要的内容,如果用户点击了好多的跨站链接,后果不可想象
- 这是一种折中最好的方案,既兼顾了易用性,也兼顾了灵活性
两方观点各有各的的道理,但我认为,Chrome 应该把这个权限放开给开发者,因为本来 DevTools 就是给开发者用的,Preserve log 并没有解决开发者跨站请求需要查看原链接的诉求,保留日志的本意应该是要保留所有的 Request 和 Response 信息,而不应该做阉割版本,应该由开发者去控制是否开启这一选项,并承担相应的结果。
不然有的时候还得通过第三方工具进行抓包或者像 issue 中讲到的那样,需要在代码层面做处理,这无疑让一个本来很简单的功能变得复杂化。
浏览器厂商的改进节奏
issue 中也有一些 Chromium 的反馈,原来认为这个需求没有必要做,而且优先级比较低,17 年的时候因为优先级和资源问题关闭了,但最近看好像又重启了,状态变成了 Open,期待之后的版本能够改善这个问题。
总结
以上是对 Preserve log 做了一个简单的介绍,如果在开发中真的遇到了上面的问题,解决方案可以考虑用以下几种方案:
1、使用 Firefox 浏览器(目前貌似用的人比较少)
2、如 issue 中所说,通过在代码中打点来进行调试,“window.onunload = function() {debugger;}”,但实际应用起来不太方便使用 Charles 等抓包工具进行抓包
作者:ES2049
链接:https://segmentfault.com/a/1190000041036021