你点开一个网页,几秒后内容就刷出来了——这背后,浏览器和服务器之间已经完成了一次「密谈」。而这场对话里,响应头(Response Headers)就是服务器递给浏览器的那张小纸条,上面写着怎么处理接下来的数据。
响应头长啥样?
打开 Chrome,按 F12 → 切到 Network 标签 → 刷新页面 → 点开任意一个请求,再点 Headers,就能看到一串以 Key: Value 形式排列的内容。比如:
Content-Type: text/html; charset=utf-8
Cache-Control: public, max-age=3600
Set-Cookie: sessionid=abc123; Path=/; HttpOnly
Access-Control-Allow-Origin: https://example.com
X-Frame-Options: DENY
每一行都是一个响应头字段,不带换行、不加引号,大小写不敏感(但惯例首字母大写),用冒号分隔键值。
几个最常打交道的响应头
Content-Type 告诉浏览器:“我给你发的是 HTML 还是 JSON?用什么编码?” 缺了它,中文可能变乱码;写错了,比如把 application/json 写成 text/plain,前端用 response.json() 就会直接报错。
Cache-Control 是缓存的「说明书」。写 no-cache 不代表不缓存,而是每次都要向服务器确认是否过期;写 max-age=60 表示这一份响应能放心用 60 秒,不用反复问。
Set-Cookie 是服务器塞给浏览器的小纸条,用来记登录状态。加上 HttpOnly 能防 XSS 直接读取,加上 Secure 表示只在 HTTPS 下发送——这些不是可有可无的修饰,而是实打实的安全开关。
跨域时绕不开的三个头
前端调接口报 No 'Access-Control-Allow-Origin' header?八成是后端漏写了这几个头:
Access-Control-Allow-Origin: https://myapp.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
注意:Access-Control-Allow-Origin 不能设成 * 同时又带凭证(比如 Cookie),否则浏览器直接拒收。真要带登录态,就得写明确的域名。
别忽略那些「隐形推手」
X-Content-Type-Options: nosniff 能阻止浏览器「猜 MIME 类型」,避免把上传的 xxx.jpg.js 当图片执行成脚本;X-Frame-Options: DENY 或 Content-Security-Policy: frame-ancestors 'none' 能防点击劫持——这些头不显眼,但上线前漏掉一个,就可能让整站暴露在已知攻击路径下。
调试时多看一眼响应头,就像修车时掀开发动机盖——很多问题,根本不用猜,答案就明明白白写在那儿。