Node.js 跨域 CORS 简单请求与预检请求的介绍

发布于:2025-04-13 ⋅ 阅读:(30) ⋅ 点赞:(0)

目录

🌐什么是跨域(CORS)

一、简单请求示例

✅ 条件

🧩后端接口(文件名:server-simple.js | 语言:JavaScript)

🖼前端页面(文件名:simple.html | 语言:HTML)

🧪运行效果

二、预检请求示例(Preflight Request)

⚠️ 触发条件

🧩后端接口(文件名:server-preflight.js | 语言:JavaScript)

🖼前端页面(文件名:preflight.html | 语言:HTML)

🧪运行效果

✅总结

📌建议与提示


在前后端分离开发中,跨域请求(CORS)是一个常见但容易让初学者困惑的问题。本文通过简单案例,帮你快速搞懂两种常见的跨域请求:

  • ✅ 简单请求(Simple Request)

  • ⚠️ 预检请求(Preflight Request)

我们将用 Node.js + Express 搭建后端接口,配合前端 HTML 页面演示跨域行为。文章包括完整代码与运行结果,适合初学者复制使用。


🌐什么是跨域(CORS)

跨域资源共享(CORS) 是浏览器的安全策略,当前端网页请求了不同源的服务器资源(协议、域名或端口不同),就需要遵循 CORS 规范。


一、简单请求示例

✅ 条件

只满足下面几个条件的请求才被浏览器认为是“简单请求”:

  • 请求方法是:GETPOSTHEAD

  • 请求头是:AcceptContent-Type(值是 application/x-www-form-urlencodedmultipart/form-datatext/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>

🧪运行效果

  1. 启动后端:node server-simple.js

  2. 打开 simple.html,点击按钮

  3. 弹窗显示:收到响应:这是一个简单请求的响应

✅ 没有任何报错,因为满足“简单请求”的条件


二、预检请求示例(Preflight Request)

⚠️ 触发条件

如果请求包含:

  • 请求方法是 PUTDELETE、或自定义方法

  • Content-Type 不是 application/x-www-form-urlencodedmultipart/form-datatext/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>

🧪运行效果

  1. 启动后端:node server-preflight.js

  2. 打开 preflight.html,点击按钮

  3. 弹窗显示:收到响应:{"message":"这是一个预检请求的响应","body":{"data":"12345"}}

✅ Chrome 控制台可以看到浏览器先发送 OPTIONS 请求,表示触发了“预检”


✅总结

类型 触发条件 是否有预检请求 示例
简单请求 方法是 GET/POST,常见头部 ✔️
预检请求 使用复杂头部或方法(PUT等) ✔️

📌建议与提示

  • 不建议后端直接设置 Access-Control-Allow-Origin: *,线上建议按域名限制

  • 用浏览器开发者工具观察请求行为非常重要

  • 建议使用 CORS 插件中间件 简化设置


如果你觉得这篇文章对你有帮助,欢迎点赞、收藏或分享给需要的朋友~
下次我们会介绍如何用 cors 中间件自动处理跨域配置 👋


需要我把这篇文章整理成 Markdown 源文件或者博客模板也可以告诉我~

 


网站公告

今日签到

点亮在社区的每一天
去签到