HTTP Response中的CORS Headers

  • Access-Control-Allow-Credentials
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Origin
  • Access-Control-Max-Age

这四个都是 CORS(Cross-Origin Resource Sharing,跨域资源共享) 机制中的 HTTP Response Header,用来告诉浏览器是否允许来自其他域名的网页访问当前服务器资源

假设有这样一个场景:

复制代码
前端(浏览器)
https://app.example.com
        │
        │ AJAX / fetch()
        ▼
后端 API
https://api.example.com

由于域名不同(app.example.comapi.example.com),浏览器会认为这是跨域请求 ,这时候服务器需要返回一些 Access-Control-* 响应头。


1. Access-Control-Allow-Origin

这是最重要的 CORS Header。

它告诉浏览器:

哪些网站可以访问我的资源?

例如:

复制代码
Access-Control-Allow-Origin: https://app.example.com

表示:

只有

复制代码
https://app.example.com

这个网站可以访问 API。

例如:

复制代码
GET https://api.example.com/user

浏览器收到 Response:

复制代码
HTTP/1.1 200 OK

Access-Control-Allow-Origin: https://app.example.com

浏览器发现:

自己的 Origin 是

复制代码
https://app.example.com

和 Response 一致。

于是:

✅ 允许 JavaScript 读取 Response。


如果服务器返回

复制代码
Access-Control-Allow-Origin: *

表示:

任何网站都可以访问。

例如:

复制代码
https://google.com
https://facebook.com
https://abc.com

都可以调用。


如果没有这个 Header:

复制代码
(no Access-Control-Allow-Origin)

浏览器会直接报:

复制代码
Access to fetch at ...
has been blocked by CORS policy

2. Access-Control-Allow-Methods

这个 Header 告诉浏览器:

允许哪些 HTTP Method。

例如:

复制代码
Access-Control-Allow-Methods:
GET, POST, PUT, DELETE

表示:

允许:

复制代码
GET
POST
PUT
DELETE

不允许:

复制代码
PATCH
OPTIONS
TRACE

例如:

浏览器想发送:

复制代码
DELETE /user/123

浏览器先会问服务器:

复制代码
OPTIONS /user/123

服务器回答:

复制代码
Access-Control-Allow-Methods:
GET, POST

浏览器发现:

DELETE 不在里面。

于是:

❌ 不允许发送 DELETE。


3. Access-Control-Allow-Credentials

这是很多人容易搞混的 Header。

它表示:

是否允许浏览器携带身份信息(Credentials)。

Credentials 包括:

  • Cookie
  • Session
  • TLS Client Certificate
  • HTTP Authentication

例如:

浏览器:

复制代码
fetch(url, {
    credentials: "include"
})

浏览器会带上:

复制代码
Cookie:
SESSIONID=abc123

但是服务器必须回答:

复制代码
Access-Control-Allow-Credentials: true

浏览器才允许:

✅ 带 Cookie。


如果服务器返回:

复制代码
Access-Control-Allow-Credentials: false

或者没有:

复制代码
Access-Control-Allow-Credentials

浏览器会:

❌ 不发送 Cookie。


注意:

这个 Header 不能和

复制代码
Access-Control-Allow-Origin: *

一起使用。

例如:

复制代码
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

浏览器会认为:

复制代码
非法!

因为:

不可能允许所有网站都携带你的 Cookie。

所以:

如果允许 Credentials,

必须明确写:

复制代码
Access-Control-Allow-Origin:
https://app.example.com

不能写:

复制代码
*

4. Access-Control-Max-Age

这个 Header 表示:

浏览器可以缓存 Preflight(OPTIONS)请求多久。

例如:

第一次:

浏览器:

复制代码
OPTIONS /api/user

服务器:

复制代码
Access-Control-Allow-Origin:
https://app.example.com

Access-Control-Allow-Methods:
GET, POST

Access-Control-Max-Age:
600

表示:

复制代码
600 秒

也就是:

10 分钟。

浏览器会记住:

复制代码
GET
POST
允许

以后:

10 分钟内再发:

复制代码
GET
POST

浏览器:

不会再发 OPTIONS。

直接发:

复制代码
GET

节省一次网络请求。


如果:

复制代码
Access-Control-Max-Age: 86400

表示:

复制代码
24 小时

浏览器一天内不会再问。


四个 Header 的关系

浏览器发起跨域请求时,大致流程如下:

复制代码
Browser
    │
    │ OPTIONS(Preflight)
    ▼
Server

服务器返回:

复制代码
Access-Control-Allow-Origin:
https://app.example.com

Access-Control-Allow-Methods:
GET, POST

Access-Control-Allow-Credentials:
true

Access-Control-Max-Age:
600

浏览器逐项检查:

复制代码
Origin 是否允许?
        │
        ▼
Method 是否允许?
        │
        ▼
是否允许 Cookie?
        │
        ▼
缓存多久?

全部通过后:

复制代码
真正发送 GET / POST 请求

总结

Header 作用 示例
Access-Control-Allow-Origin 指定哪些源(Origin)可以访问资源 https://app.example.com*
Access-Control-Allow-Methods 指定允许的 HTTP 方法 GET, POST, PUT, DELETE
Access-Control-Allow-Credentials 是否允许浏览器携带 Cookie、Session 等身份凭据 true
Access-Control-Max-Age 浏览器缓存预检(Preflight)结果的时间(秒) 60086400

可以把这四个响应头理解成一组权限控制:

  • Allow-Origin可以访问?
  • Allow-Methods :可以执行什么操作
  • Allow-Credentials :访问时能不能携带身份凭据(Cookie、Session 等)?
  • Max-Age :这些规则浏览器可以缓存多久,避免重复发送预检请求。
相关推荐
念何架构之路2 小时前
moby-http-api-server
网络·网络协议·http
namexingyun2 小时前
Scaling Law bug实战启示:从“虚胖“到“精瘦“的算力效率革命
开发语言·网络·人工智能·bug·ai编程
云栖梦泽在2 小时前
原生 IP、机房 IP、住宅 IP、广播 IP 有何不同?从网络身份到 ASN 识别的技术科普
网络·网络协议·tcp/ip·性能优化
AI创界者2 小时前
【实战演练】基于 Kali Linux 的自动化漏洞扫描与安全加固指南
网络·安全·web安全
从零开始的代码生活_3 小时前
Linux epoll 多路转接详解
linux·运维·网络·后端·tcp/ip·计算机网络·php
小鹿软件办公3 小时前
通过调整编码参数使用 VLC 媒体播放器无损压缩视频方法
运维·网络·音视频
Zhan8611244 小时前
西班牙股票行情数据API的WebSocket接入:IBEX35指数实时推送与数据清洗
python·websocket·网络协议
yqcoder5 小时前
什么是 Math 对象
网络·网络协议·udp
Piko61415 小时前
H3C IRF2 堆叠实战:打造高可靠核心交换网络
运维·网络·笔记