• 作者:老汪软件技巧
  • 发表时间:2024-10-11 11:02
  • 浏览量:

前言

在现代 Web 开发中,浏览器的同源策略是一项非常重要的安全机制,它可以有效防止恶意网站未经授权地访问用户的敏感信息。但它同时也给开发者带来了跨域资源请求的难题。尤其是在微前端架构下,不同子应用往往会独立部署在不同域名下,这种跨域限制就会带来 API 调用上的挑战。

本文将详细介绍如何通过 Node.js 代理服务来解决这些问题,帮助你实现跨域 API 请求,确保应用的安全性和兼容性。

大家好,我是芝士,欢迎点此扫码加我微信Hunyi32交流,最近创建了一个低代码/前端工程化交流群,欢迎加我微信 Hunyi32 进群一起交流学习,也可关注我的公众号[ 前端界 ] 持续更新优质技术文章

为什么需要代理服务?

代理服务器在跨域场景中充当了中介,它使得前端页面只需与同源的代理服务器进行通信,而代理服务器再代为与跨域的 API 进行交互。这样可以有效规避浏览器的跨域限制,同时保证 Cookie 等身份验证信息能够顺利传递给目标服务器。

这种方案应用场景非常广泛,尤其是在以下两个业务环境中:

微前端架构:每个子应用可能独立部署在不同的域名,但需要与主应用共享登录态。通过代理服务器,子应用可以通过主应用代理访问跨域的 API,解决跨域问题的同时,确保用户身份验证信息(例如 Cookie)能正确传递。

单页应用(SPA) :客户端可以通过代理服务器访问多个不同域名的 API,而无需担心跨域限制。这在需要调用第三方 API 或微服务架构中十分常见。

实现代理服务的核心流程

整个代理服务的流程可以分为四个步骤:

客户端请求代理服务器

客户端发起请求 :3000/proxy/data,并携带相关的 Cookie(通过 credentials: 'include' 确保 Cookie 传递)。代理服务器接收请求并转发

代理服务器接收到请求后,会将其转发到目标服务器 ,同时传递客户端的 Cookie 到目标服务器,以确保身份验证。目标服务器处理请求

目标服务器根据 Cookie 检查是否存在有效的 sessionId,如果存在有效的会话,则返回用户数据;否则返回未授权错误。代理服务器将响应返回客户端

代理服务器接收目标服务器的响应并将其返回给客户端。流程图

请求跨域问题怎么解决_请求跨域是什么意思_

为了更好地理解整个代理过程,画了一个流程图

代码实现1. 代理服务器代码

通过 Node.js 使用 express 和 http-proxy 模块实现一个代理服务器,并确保 Cookie 的正确传递。

const express = require('express');
const httpProxy = require('http-proxy');
const cookieParser = require('cookie-parser');
const app = express();
const proxy = httpProxy.createProxyServer();
// 使用 cookie-parser 中间件解析 Cookie
app.use(cookieParser());
// 代理请求的路由
app.all('/proxy/*', (req, res) => {
  // 假设请求的目标是 https://api.example.com/data
  const targetUrl = `https://api.example.com/${req.params[0]}`;
  // 代理请求的选项,传递 Cookie 和其他必要的请求头
  const options = {
    target: targetUrl,
    changeOrigin: true,  // 使目标服务器看到的请求 Host 是目标服务器而不是代理服务器的 Host
    headers: {
      'Cookie': req.headers.cookie || ''  // 将客户端发送的 Cookie 传递给目标服务器
    }
  };
  // 将请求代理到目标服务器
  proxy.web(req, res, options, (error) => {
    console.error(`Proxy request to ${targetUrl} failed:`, error);
    res.status(500).send('Proxy request failed');
  });
});
// 代理服务启动
app.listen(3000, () => {
  console.log('Proxy server is running on http://localhost:3000');
});

2. 客户端代码

使用 fetch 方法向代理服务器发起请求,并确保 Cookie 在请求中传递。

fetch('http://localhost:3000/proxy/data', {
  method: 'GET',
  credentials: 'include' // 保持 Cookie 在请求中传递
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error('Request failed', err));

3. 目标服务器代码

目标服务器处理请求并根据客户端传递的 Cookie 返回相应的数据。

const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
const port = 8080; // 假设目标服务器运行在 8080 端口
// 使用 cookie-parser 中间件解析 Cookie
app.use(cookieParser());
// 模拟的用户数据
const users = {
  'session123': { id: 1, name: '前端界', email: 'xiaoming@163.com' },
  'session456': { id: 2, name: '芝士', email: 'xiaohong@163.com' }
};
// 处理 /data 路由的请求
app.get('/data', (req, res) => {
  const sessionCookie = req.cookies.sessionId;  // 获取请求中的 Cookie,假设叫做 sessionId
  if (!sessionCookie || !users[sessionCookie]) {
    // 如果没有 Cookie 或者 Cookie 不正确,返回 401 未授权
    return res.status(401).json({ error: 'Unauthorized: Invalid session' });
  }
  // 如果 Cookie 有效,返回该用户的数据
  const userData = users[sessionCookie];
  res.json({
    message: 'Data fetched successfully',
    user: userData
  });
});
// 启动目标服务器
app.listen(port, () => {
  console.log(`Target server running on http://localhost:${port}`);
});

性能优化与安全考虑缓存机制

代理服务器可以引入缓存机制,减少重复的请求,提升 API 请求性能。常见的方案是使用 redis 或 memory-cache 来缓存目标服务器的响应。

安全性

大家好,我是芝士,最近创建了一个低代码/前端工程化交流群,欢迎点此扫码加我微信Hunyi32交流,也可关注我的公众号[ 前端界 ] 持续更新优质技术文章

总结

通过本文的示例,详细讲解了如何使用 Node.js 代理服务来解决跨域 API 请求问题,特别是在微前端架构和单页应用中的应用场景中。代理服务器不仅能够解决跨域问题,还可以确保登录态、Cookie 等关键信息的正确传递。希望这篇文章能帮助小伙伴们在实际开发中顺利解决跨域请求的问题。