为什么crossorigin属性对preconnect链接至关重要?
crossorigin属性会影响preconnect阶段? 首先得说,你对preconnect和crossorigin的基础理解完全没问题:
preconnect就是让浏览器提前搞定目标主机的DNS解析、TCP连接,要是HTTPS的话还会完成TLS握手,这些步骤全都在发任何HTTP数据包之前做完,HTTP版本也会在TLS握手的ALPN环节协商好。crossorigin的三种行为也没说错:- 不带这个属性:请求里不会发
Origin头,服务器自然也不会返回CORS相关的响应头 anonymous模式:会发Origin头,支持CORS,但不会带Cookie和认证信息use-credentials模式:不仅发Origin头,还会带Cookie和认证头,支持带凭证的CORS
- 不带这个属性:请求里不会发
接下来解答你的核心疑问:虽然Origin、Cookie、认证信息都是在HTTP请求阶段才发,但crossorigin会影响浏览器对preconnect创建的连接的复用规则,甚至是TLS握手的细节,所以它能影响到preconnect阶段。具体来说有这几个原因:
1. 浏览器按CORS上下文分开管理连接池
浏览器会给不同的CORS场景单独维护连接池:
- 不带
crossorigin属性的请求,属于「同源/非CORS请求上下文」 - 带
crossorigin="anonymous"或use-credentials的请求,属于「CORS请求上下文」(而且这俩还因为要不要带凭证,被分成了两个子场景)
preconnect创建的连接会被放到对应的连接池里。如果后续实际请求的CORS上下文和preconnect指定的不匹配,浏览器根本没法复用这个提前建好的连接,那preconnect等于白做了。所以浏览器在执行preconnect的时候,必须根据crossorigin属性提前确定这个连接归哪个池子,避免做无用功。
2. 带凭证的CORS场景会影响TLS握手细节
当你用crossorigin="use-credentials"的时候,浏览器在TLS握手阶段可能会带上和凭证相关的TLS扩展(比如和Cookie会话相关的信息,或者客户端证书的协商)。虽然凭证本身是在HTTP阶段发,但TLS层的这些前置操作得提前知道要不要带凭证,而crossorigin属性就是判断的依据。
3. 提前适配CORS预请求的优化
对于需要发预请求(Preflight)的CORS请求,浏览器提前通过crossorigin属性知道这是个CORS场景,preconnect就能提前为后续的预请求和实际请求建好连接;要是没指定正确的crossorigin,浏览器没法提前预判是CORS请求,也就没法针对性地优化连接建立的流程。
说白了,crossorigin属性就是提前告诉浏览器「后续请求的CORS场景是什么样的」,浏览器会根据这个信息调整preconnect的连接创建策略、连接池归属,甚至TLS握手的细节,确保提前建好的连接能被后续的实际请求用上——这就是它能影响preconnect阶段的核心原因。
内容的提问来源于stack exchange,提问作者user3009344

