源码角度理解 CORS

Photo by Museums Victoria on Unsplash

Cross-Origin Resource Sharing (CORS) 也叫做跨域资源共享。浏览器会自动判别一个 HTTP 请求是否跨域,并自动与后端服务协商。由后端服务来决定是否接受此跨域请求。学习 CORS 中协商过程需要两步,一是通过跨域资源共享 CORS 详解MDN 上的手册,二是通过源码。

koa 中有个中间件就叫做 @koa/cors。此中间件根据 CORS 协议规范,创建了一个与浏览器交互的 CORS 处理函数。本文从此中间件入手,结合手册详细讲述 CORS 的后端实现。

跨域请求的标识——Origin

无论简单请求还是非简单请求,浏览器都会在请求头字段中加入 Origin。我们可以通过查找请求头中是否有 Origin 来判断此请求是否为跨域请求。

简单请求还是非简单请求

当浏览器发现请求是简单请求时,浏览器会直接改造请求头。当请求是非简单请求时,浏览器会首先向后端发起一个 Preflight 请求,得到后端应用程序的答复后再决定是否继续发起跨域请求。 Preflight 请求用的是 OPTIONS 方法。这个特征也是源码中用来判断跨域请求是简单请求还是非简单请求的办法。

简单请求

若跨域请求是简单请求,后端服务根据协议返回 Access-Control-Allow-Origin(必须)、 Access-Control-Allow-Credentials(可选) 、Access-Control-Expose-Headers (可选)三个头字段,分别代表是否同意跨域的请求,是否同意携带认证信息,是否暴露其他头信息。

Preflight 请求

非简单请求时,浏览器会想后端在请求发起一个 Preflight 请求。此请求头部带上 Access-Control-Request-Method 和 Access-Control-Request-Headers 两个字段,后端程序对这两个字段进行解析。前者非关键信息,仅仅用来判断是否属于非简单请求,后者作为设定 Access-Control-Allow-Headers 的参考。

Acess-Control-Max-Age(可选)、 Access-Control-Allow-Credential(可选)非必选信息,源码中根据后台开发者进行指定。 Access-Control-Allow-Origin (必须)默认设定为所有方法。Access-Control-Allow-Headers (必须)设置为与 Access-Control-Request-Headers 相同。

发表评论

电子邮件地址不会被公开。 必填项已用*标注