前端最普遍的就是遇到跨域,这个问题一般都会用node框架例如egg,express工具编写
下面就开始看看项目架构
最主要的文件是proxy.js
const express = require('express');
const axios = require('axios');
const cors = require('cors');
const multer = require('multer');
const path = require('path');
const FormData = require('form-data'); // 引入 form-data
const iconv = require('iconv-lite');
const fs = require('fs');
const app = express();
//前端项目端口
const port = 3010;
// 设置 multer 存储引擎
const upload = multer(); // 默认使用内存存储
// 配置 CORS
app.use(
cors({
origin: 'http://localhost:9528', // 替换为你的前端地址
credentials: true, // 允许携带 Cookie
})
);
// 解析 JSON 请求体
app.use(express.json());
// 解析 multipart/form-data 请求体
app.use(upload.any()); // 解析 multipart 数据,任何字段都可以处理
// 中转路由
app.all('/proxy/*', async (req, res) => {
try {
// 构造目标 URL 这是你要请求的接口路径
// const targetUrl = '';
// 请求方法和数据
const { method, body, query, headers } = req;
// 判断请求是否包含文件
if (req.files && req.files.length > 0) {
// 处理文件上传的请求
const form = new FormData();
req.files.forEach(file => {
const decodedName = iconv.decode(Buffer.from(file.originalname, 'binary'), 'utf-8');
// 如果仍有乱码,可以直接设置默认文件名,避免后续问题
file.originalname = decodedName || 'unknown_file';
form.append(file.fieldname, file.buffer, {
filename: file.originalname,
contentType: file.mimetype,
});
});
// 如果请求体中有其他字段,添加到 form-data
Object.keys(body).forEach(key => {
form.append(key, body[key]);
});
// 获取 form-data 请求头
const formHeaders = form.getHeaders();
// 转发请求
const response = await axios({
url: targetUrl,
method,
headers: {
...formHeaders, // 添加 form-data 的 headers
host: new URL(targetUrl).host, // 替换 Host 为目标主机
cookie: headers.cookie || '', // 转发客户端传递的 Cookie
},
params: query, // GET 参数
data: form, // 请求体,包含表单数据
timeout: 50000, // 可选:设置超时时间
});
// 设置目标接口的 Cookie 到响应头
if (response.headers['set-cookie']) {
res.setHeader('set-cookie', response.headers['set-cookie']);
}
// 转发响应
res.status(response.status).send(response.data);
} else {
// 处理普通的 JSON 请求
const response = await axios({
url: targetUrl,
method,
headers: {
...headers,
host: new URL(targetUrl).host, // 替换 Host 为目标主机
cookie: headers.cookie || '', // 转发客户端传递的 Cookie
},
params: query, // GET 参数
data: body, // JSON 请求体
timeout: 5000, // 可选:设置超时时间
});
// 设置目标接口的 Cookie 到响应头
if (response.headers['set-cookie']) {
res.setHeader('set-cookie', response.headers['set-cookie']);
}
// 转发响应
res.status(response.status).send(response.data);
}
} catch (error) {
console.error('Proxy error:', error.message);
// 处理错误
if (error.response) {
res.status(error.response.status).send(error.response.data);
} else {
res.status(500).send({ error: 'Internal Server Error' });
}
}
});
// 静态资源
app.use(express.static(path.join(__dirname, 'public')));
// 启动服务
app.listen(port, () => {
console.log(`Proxy server running at http://localhost:${port}`);
});
这样你前端项目就可以用http://localhost:3010/proxy/打开