上一篇
2025年7月最新消息:随着Web应用架构日益复杂,跨域请求已成为前端开发中的常见需求,最新Node.js 22版本进一步优化了内置HTTP模块性能,使得开发者能够更高效地构建跨域友好的API服务,据统计,超过78%的企业级应用需要处理跨域数据交互问题。
跨域问题源于浏览器的同源策略(Same-Origin Policy),这是现代浏览器最基本的安全功能之一,当你的前端页面运行在http://a.com
,而尝试请求http://b.com
的API时,浏览器就会阻止这个请求。
在实际开发中,前后端分离架构非常普遍:
http://localhost:3000
http://localhost:8000
我们先从最基础的Node.js HTTP服务器开始:
const http = require('http'); const server = http.createServer((req, res) => { if (req.url === '/api/data' && req.method === 'GET') { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ message: "基础接口响应成功" })); } else { res.writeHead(404); res.end('Not Found'); } }); server.listen(8000, () => { console.log('服务器运行在 http://localhost:8000'); });
这个简单例子创建了一个监听8000端口的服务器,当访问/api/data
时会返回JSON数据。
实际开发中我们更常用Express这样的框架:
const express = require('express'); const app = express(); // 中间件:解析JSON请求体 app.use(express.json()); // 示例数据 let products = [ { id: 1, name: '商品A', price: 100 }, { id: 2, name: '商品B', price: 200 } ]; // GET /api/products app.get('/api/products', (req, res) => { res.json(products); }); // POST /api/products app.post('/api/products', (req, res) => { const newProduct = req.body; products.push(newProduct); res.status(201).json(newProduct); }); app.listen(8000, () => { console.log('API服务运行在 http://localhost:8000'); });
const cors = require('cors'); // 允许所有来源 app.use(cors()); // 或者配置特定来源 app.use(cors({ origin: 'http://localhost:3000', methods: ['GET', 'POST', 'PUT', 'DELETE'], allowedHeaders: ['Content-Type', 'Authorization'] }));
如果不使用cors中间件,可以手动设置:
app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); // 处理预检请求(OPTIONS) if (req.method === 'OPTIONS') { return res.sendStatus(200); } next(); });
在开发环境中,前端框架通常支持代理配置:
// vite.config.js (Vite项目) export default { server: { proxy: { '/api': { target: 'http://localhost:8000', changeOrigin: true, rewrite: path => path.replace(/^\/api/, '') } } } }
虽然现在很少用,但在某些特殊场景可能有用:
app.get('/api/jsonp', (req, res) => { const callback = req.query.callback; const data = { message: "JSONP响应" }; res.type('text/javascript'); res.send(`${callback}(${JSON.stringify(data)})`); });
当请求需要携带cookie或认证信息时:
app.use(cors({ origin: 'http://localhost:3000', credentials: true })); // 前端也需要配置 // fetch(url, { credentials: 'include' })
const allowOrigins = ['http://localhost:3000', 'https://myapp.com']; app.use((req, res, next) => { const origin = req.headers.origin; if (allowOrigins.includes(origin)) { res.header('Access-Control-Allow-Origin', origin); res.header('Access-Control-Allow-Credentials', 'true'); } if (req.method === 'OPTIONS') { res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.status(200).end(); return; } next(); });
res.header('Access-Control-Max-Age', '86400'); // 24小时
const allowedOrigins = process.env.NODE_ENV === 'production' ? ['https://myapp.com'] : ['http://localhost:3000'];
credentials
选项no-cache
头const express = require('express'); const cors = require('cors'); const app = express(); // 配置 const PORT = 8000; const isProduction = process.env.NODE_ENV === 'production'; const allowedOrigins = isProduction ? ['https://myapp.com'] : ['http://localhost:3000']; // 中间件 app.use(express.json()); app.use(express.urlencoded({ extended: true })); // CORS配置 app.use(cors({ origin: (origin, callback) => { if (!origin || allowedOrigins.includes(origin)) { callback(null, true); } else { callback(new Error('不允许的请求来源')); } }, credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE'], allowedHeaders: ['Content-Type', 'Authorization'] })); // 路由 app.get('/api/user', (req, res) => { res.json({ name: '张三', age: 30 }); }); app.post('/api/login', (req, res) => { const { username, password } = req.body; // 验证逻辑... res.json({ token: '模拟token', user: { username } }); }); // 错误处理 app.use((err, req, res, next) => { console.error(err); res.status(500).json({ error: err.message }); }); // 启动服务器 app.listen(PORT, () => { console.log(`服务器运行在 http://localhost:${PORT}`); });
Node.js提供了多种灵活的方式来解决跨域问题,从简单的CORS头设置到复杂的代理服务器方案,选择哪种方案取决于你的具体需求:
跨域问题本质是浏览器安全策略,服务端只是通过响应头告诉浏览器哪些跨域请求是被允许的,掌握这些技术后,你就能轻松构建前后端分离的现代化Web应用了。
本文由 鱼姗 于2025-07-31发表在【云服务器提供商】,文中图片由(鱼姗)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/496895.html
发表评论