目录
🧩后端接口(文件名:server-simple.js | 语言:JavaScript)
🖼前端页面(文件名:simple.html | 语言:HTML)
🧩后端接口(文件名:server-preflight.js | 语言:JavaScript)
🖼前端页面(文件名:preflight.html | 语言:HTML)
在前后端分离开发中,跨域请求(CORS)是一个常见但容易让初学者困惑的问题。本文通过简单案例,帮你快速搞懂两种常见的跨域请求:
✅ 简单请求(Simple Request)
⚠️ 预检请求(Preflight Request)
我们将用 Node.js + Express 搭建后端接口,配合前端 HTML 页面演示跨域行为。文章包括完整代码与运行结果,适合初学者复制使用。
🌐什么是跨域(CORS)
跨域资源共享(CORS) 是浏览器的安全策略,当前端网页请求了不同源的服务器资源(协议、域名或端口不同),就需要遵循 CORS 规范。
一、简单请求示例
✅ 条件
只满足下面几个条件的请求才被浏览器认为是“简单请求”:
请求方法是:
GET
、POST
或HEAD
请求头是:
Accept
、Content-Type
(值是application/x-www-form-urlencoded
、multipart/form-data
、text/plain
)请求没有设置自定义头部
🧩后端接口(文件名:server-simple.js
| 语言:JavaScript)
// server-simple.js
const express = require('express');
const app = express();
const port = 3000;
// 设置允许跨域的头部
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*'); // 允许所有域访问
next();
});
app.get('/simple', (req, res) => {
res.send('这是一个简单请求的响应');
});
app.listen(port, () => {
console.log(`Simple server running at http://localhost:${port}`);
});
🖼前端页面(文件名:simple.html
| 语言:HTML)
<!-- simple.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>简单请求演示</title>
</head>
<body>
<h2>点击按钮发送跨域简单请求</h2>
<button onclick="sendRequest()">发送请求</button>
<script>
function sendRequest() {
fetch('http://localhost:3000/simple')
.then(response => response.text())
.then(data => alert('收到响应:' + data))
.catch(error => console.error('请求失败', error));
}
</script>
</body>
</html>
🧪运行效果
启动后端:
node server-simple.js
打开
simple.html
,点击按钮弹窗显示:
收到响应:这是一个简单请求的响应
✅ 没有任何报错,因为满足“简单请求”的条件
二、预检请求示例(Preflight Request)
⚠️ 触发条件
如果请求包含:
请求方法是
PUT
、DELETE
、或自定义方法Content-Type
不是application/x-www-form-urlencoded
、multipart/form-data
、text/plain
自定义请求头(如
X-Custom-Header
)
浏览器会先自动发送一个 OPTIONS
请求(预检请求)确认服务器是否允许,再正式发出请求。
🧩后端接口(文件名:server-preflight.js
| 语言:JavaScript)
// server-preflight.js
const express = require('express');
const app = express();
const port = 4000;
app.use(express.json());
// 设置允许跨域的头部(包括预检)
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*'); // 允许所有源
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); // 允许的方法
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Custom-Header'); // 允许的自定义头
if (req.method === 'OPTIONS') {
return res.sendStatus(204); // 预检请求直接返回
}
next();
});
app.post('/preflight', (req, res) => {
res.json({ message: '这是一个预检请求的响应', body: req.body });
});
app.listen(port, () => {
console.log(`Preflight server running at http://localhost:${port}`);
});
🖼前端页面(文件名:preflight.html
| 语言:HTML)
<!-- preflight.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>预检请求演示</title>
</head>
<body>
<h2>点击按钮发送跨域预检请求</h2>
<button onclick="sendPreflight()">发送请求</button>
<script>
function sendPreflight() {
fetch('http://localhost:4000/preflight', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Custom-Header': 'test'
},
body: JSON.stringify({ data: '12345' })
})
.then(response => response.json())
.then(data => alert('收到响应:' + JSON.stringify(data)))
.catch(error => console.error('请求失败', error));
}
</script>
</body>
</html>
🧪运行效果
启动后端:
node server-preflight.js
打开
preflight.html
,点击按钮弹窗显示:
收到响应:{"message":"这是一个预检请求的响应","body":{"data":"12345"}}
✅ Chrome 控制台可以看到浏览器先发送 OPTIONS
请求,表示触发了“预检”
✅总结
类型 | 触发条件 | 是否有预检请求 | 示例 |
---|---|---|---|
简单请求 | 方法是 GET/POST,常见头部 | 否 | ✔️ |
预检请求 | 使用复杂头部或方法(PUT等) | 是 | ✔️ |
📌建议与提示
不建议后端直接设置
Access-Control-Allow-Origin: *
,线上建议按域名限制用浏览器开发者工具观察请求行为非常重要
建议使用 CORS 插件中间件 简化设置
如果你觉得这篇文章对你有帮助,欢迎点赞、收藏或分享给需要的朋友~
下次我们会介绍如何用 cors
中间件自动处理跨域配置 👋
需要我把这篇文章整理成 Markdown 源文件或者博客模板也可以告诉我~