跨域访问
浏览器特有的问题
在所处源的网站访问其他源的时候,浏览器出于安全考虑,会做出很多限制。这个叫做同源策略。
同源的定义:协议 + 域名 + 端口
主要限制有以下:
- DOM 访问限制(不能读取和操作非同源的 DOM)
- Cookie 访问限制
- Ajax 响应数据限制(可以给非同源发送请求,接受到的数据未通过校验,不会移交给开发者)
注意:<iframe>元素可以放入页面,页面非同源时就不能操作元素了。
但是 <link>,<script>,<img>元素很可能跨域,但是浏览器通常对标签域不做处理,对开发几乎无影响。
CORS 跨域问题
Cross-origin Resource Sharing跨域资源共享,用于控制浏览器校验跨域请求的一套规范。
实际上浏览器能够收到非同源服务器返回的数据,但是浏览器的同源策略很可能不会将数据交出来。
通常解决方案就是处理 校验这一步,使得我们可以获取返回来的数据。
CORS 将请求分为了简单请求和复杂请求。具体区分自行去查阅,该文只做机制了解。
复杂请求在发送之前浏览器会自动发送一个预检请求,询问非同源服务器是否运行跨域请求。
预检请求:浏览器自动发送的一个 options请求,预检请求会包含以下特定的请求头:
(1) Origin
- 作用:表示请求的来源(协议 + 域名 + 端口)。
(2) Access-Control-Request-Method
- 作用:表示实际请求将使用的 HTTP 方法(如
GET、POST等)。
(3) Access-Control-Request-Headers
- 作用:表示实际请求中将包含的非简单请求头(如
Authorization、Content-Type等)。
(4) 其他标准请求头
预检请求还可能包含一些标准的请求头,例如:
Host:请求的目标主机。User-Agent:浏览器的用户代理信息。Accept:客户端接受的响应类型。
示例:
OPTIONS /data HTTP/1.1
Host: api.example.com
Origin: http://client.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization, Content-Type
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Accept: */*HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://client.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Max-Age: 86400
Access-Control-Allow-Credentials: truecors 库
该库可以快速简便的设置响应预检请求的响应,解决跨域问题,只需要简单配置。
const express = require('express');
const cors = require('cors');
const app = express();
// 配置 CORS
app.use(cors({
origin: 'http://client.example.com', // 允许的来源
methods: ['GET', 'POST', 'PUT', 'DELETE'], // 允许的 HTTP 方法
allowedHeaders: ['Content-Type', 'Authorization', 'X-Custom-Header'], // 允许的请求头
}));
app.get('/data', (req, res) => {
res.json({ message: 'This is a CORS-enabled response' });
});
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});