业务过程中, 有个服务使用无头浏览器专门用来为网页进行截图.
但是当时出现了一个问题在于本地开发环境进行截图是没有任何问题的, 但是在服务器部署后同一个网页部分的截图不一致问题.
主要体现在有个iframe标签嵌入的内容无法被正常截图.
经过对网络请求的分析发现, 页面会有一个发送给测试环境官网的请求来获取iframe标签.
形式如: https://xxx.test.com/api/iframe
这时出现了第一个问题, 因为测试环境是连接公司VPN来访问, 那么也就意味着dns解析是通过公司本地dns服务器来解析处具体IP来访问
那么部署到公有云的k8s的pod中, 使用的公有云的dns, 那么肯定无法正确发出这个请求.
所以修改为k8s中pod可以解析的dns, 请求最后发出的是 http://server/api/iframe

解析过程如下:
用户发起DNS查询
当用户在浏览器中输入域名时,浏览器会首先检查本地缓存中是否有该域名对应的IP地址。如果有,则直接使用该IP地址;如果没有,则发起DNS查询。
操作系统缓存
操作系统会检查自身的DNS缓存中是否有该域名对应的IP地址。如果有,则返回IP地址;如果没有,则查询配置的DNS服务器。
查询本地域名服务器(ISP的DNS服务器)
本地域名服务器是由用户的互联网服务提供商(ISP)提供的DNS服务器。当操作系统没有找到缓存记录时,会向本地域名服务器发起查询请求。
递归查询
如果本地域名服务器没有该域名的缓存记录,它会代替用户进行递归查询,逐级查找IP地址。这包括以下几个步骤:
a. 根域名服务器
本地域名服务器首先会查询根域名服务器(Root Name Server),根服务器掌握所有顶级域(如.com、.org)的信息。
b. 顶级域名服务器(TLD Name Server)
根服务器会返回相应顶级域名服务器的地址(例如,.com域名的服务器)。然后本地域名服务器会向该顶级域名服务器发起查询请求。
c. 权威域名服务器(Authoritative Name Server)
顶级域名服务器会返回管理该具体域名(例如,example.com)的权威域名服务器地址。最终,本地域名服务器会向权威域名服务器发起查询请求。
返回结果
权威域名服务器返回该域名对应的IP地址。本地域名服务器将该IP地址缓存一段时间,以便下次查询更快,然后将IP地址返回给操作系统。
在解决上述问题后, 发现服务器部署后截图功能仍然存在问题, 仍然无法解决iframe标签未正确加载的问题.
因为服务器上的网络请求无法查看, 也没有具体日志查看, 通过很多手段最终可以确认基本还是那个请求没有发送的问题.
问题在于: 因为存在跨域的问题, 请求会先发送预检请求(OPTIONS 方法), 查看是否允许后续请求发送, 再发送我们的Post请求 http://server/api/iframe
发送预检请求是直接发送到了我们服务上, 而处理预检请求这些的都是gateway的事情, 所以这个请求仍然是没有正确得发出来.
所以我们在公有云的k8s的dns上配置好测试环境的dns解析, 然后让其请求发送到gateway, 然后正常处理就可以了.
其实这个问题在现网环境不会发生, 因为现网不存在dns无法解析这样的情况.
跨域问题是指浏览器出于安全考虑,限制从一个源(域名、协议或端口)加载的文档或脚本与来自另一个源的资源进行交互。这是浏览器的同源策略(Same-Origin Policy)导致的。
让我简要解释跨域问题的几个要点:
当浏览器发现需要发送跨域 HTTP 请求时,它会采取一系列特定的动作。这个过程通常涉及到预检请求(Preflight request)和实际请求。详细解释一下这个过程:
简单请求:
对于简单请求(如 GET、HEAD、POST 请求,且没有自定义头部,Content-Type 限于 application/x-www-form-urlencoded、multipart/form-data 或 text/plain),浏览器会:
非简单请求(需要预检):
对于非简单请求(如使用 PUT、DELETE 方法,或带有自定义头部),浏览器会:
a. 发送预检请求(OPTIONS 方法):
如果有自定义头部,还会包含 Access-Control-Request-Headers 头
b. 等待服务器对预检请求的响应:
检查 Access-Control-Max-Age(可选,指定预检请求的缓存时间)
c. 如果预检请求通过:
在实际请求中包含 Origin 头
d. 等待服务器对实际请求的响应:
再次检查 Access-Control-Allow-Origin
处理响应:
错误处理:
缓存预检请求:
在业务过程中,使用无头浏览器进行网页截图时,发现本地开发环境可以正常截图,但在服务器部署后某些网页部分截图不一致,尤其是iframe标签嵌入的内容无法正常截图。分析过程如下:
本地调试发现网页请求中,有一个请求是通过公司VPN访问的,此时DNS解析使用公司本地DNS服务器。部署到公有云的K8s中使用的DNS无法解析该请求。解决办法是修改K8s中Pod的DNS。
解决DNS问题后,截图功能仍有问题,原因是跨域请求的预检请求没有正确处理。跨域请求会先发送OPTIONS预检请求,确认允许后再发送实际请求。预检请求直接发送到服务上,而应由gateway处理。因此解决办法是在公有云K8s的DNS上配置好测试环境的DNS解析,让请求发送到gateway。
跨域问题涉及浏览器安全限制,不同源的文档和脚本不能互相操作。解决跨域问题的方法有CORS、JSONP、代理服务器和WebSocket。实际进行跨域请求时,浏览器会根据请求的复杂性决定是否需要预检,预检不通过则阻止请求。