前端项目脱离后端运行,备份后端API数据

发布于:2025-06-25 ⋅ 阅读:(19) ⋅ 点赞:(0)

问题描述:
开发过的项目老是打不开,因为离开公司后服务器用不了了。所以想着在公司开发的时候把数据都备份一下,供之后参考项目代码。

实现方法:
建一个Express服务,前端请求Express,Express代理目标服务器,通过请求api以json格式缓存到本地mocks文件夹内。第一次请求时缓存下来,第二次直接用缓存。

  1. 初始化项目
    创建一个新目录并初始化 package.json:

bash
mkdir mock-server
cd mock-server
npm init -y
安装必要的依赖:
bash
npm install express axios fs path url crypto

  1. 创建代理服务器代码
    创建 server.js 文件,内容如下:
const express = require('express');
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const url = require('url');
const crypto = require('crypto');

const app = express();
const MODE = 3; //1:根据路径生成缓存文件,2:根据路径和参数生成文件名,3:根据路径和参数和post 请求生成文件名
const PORT = 3000;
const TARGET_SERVER = 'http://192.168.0.184:6080'; // 替换为目标服务器地址

const MOCK_DIR = path.join(__dirname, 'mocks');

if (!fs.existsSync(MOCK_DIR)) {
    fs.mkdirSync(MOCK_DIR);
}

app.use(express.json());

// 工具函数:对对象进行排序序列化,用于生成稳定 hash
function sortedStringify(obj) {
    if (typeof obj !== 'object' || obj === null) return obj;
    // 如果是数组,则递归处理每一项
    if (Array.isArray(obj)) {
        return obj.map(item => sortedStringify(item));
    }
    const keys = Object.keys(obj).sort();
    const sorted = {};
    for (const k of keys) {
        sorted[k] = sortedStringify(obj[k]);
    }
    return JSON.stringify(sorted);
}

// 工具函数:生成字符串的 hash,避免文件名过长
function getHash(str) {
    return crypto.createHash('md5').update(str).digest('hex');
}

// 通用代理中间件
app.use(async (req, res) => {
    const parsedUrl = url.parse(req.url, true); // true 表示解析 query 参数
    const { pathname, query } = parsedUrl;

    // 构建缓存文件名:将 pathname 和 query 都作为标识
    const queryParamsStr = Object.entries(query)
        .sort(([a], [b]) => a.localeCompare(b)) // 排序确保 key 顺序一致(避免缓存碎片)
        .map(([k, v]) => `${k}=${v}`)
        .join('&');

    let bodyHash = '';
    let fileNameBase = ``;
    let mockFilePath = ''
    if (MODE === 1) {
        mockFilePath = path.join(MOCK_DIR, `${pathname.replace(/\//g, '_')}.json`);
    } else if (MODE === 2) {
        fileNameBase = `${pathname.replace(/\//g, '_')}${queryParamsStr ? '_' + encodeURIComponent(queryParamsStr) : ''}`;
        mockFilePath = path.join(MOCK_DIR, `${fileNameBase}.json`);
    } else if (MODE === 3) {
        const queryStr = queryParamsStr ? '_' + encodeURIComponent(queryParamsStr) : '';
        if (req.method === 'POST' && req.body && Object.keys(req.body).length > 0) {
            const bodyStr = sortedStringify(req.body);
            bodyHash = '_' + getHash(bodyStr);
            // console.log(45, bodyHash, req.body)
        }
        fileNameBase = `${pathname.replace(/\//g, '_')}${queryStr}${bodyHash}`;
        mockFilePath = path.join(MOCK_DIR, `${fileNameBase}.json`);
    }

    // 检查本地是否存在缓存数据
    if (fs.existsSync(mockFilePath)) {
        const data = fs.readFileSync(mockFilePath, 'utf8');
        try {
            const jsonData = JSON.parse(data);
            console.log(`返回缓存数据: ${pathname}`);
            return res.json(jsonData);
        } catch (e) {
            console.error(`Failed to parse cached file: ${mockFilePath}`);
        }
    }

    // 否则转发请求到目标服务器
    try {
        const targetUrl = `${TARGET_SERVER}${parsedUrl.path}`;
        console.log('targetUrl:', targetUrl);
        const response = await axios({
            method: req.method,
            url: targetUrl,
            data: req.body,
            headers: req.headers,
        });

        // 将响应数据缓存到本地
        fs.writeFileSync(mockFilePath, JSON.stringify(response.data, null, 2), 'utf8');
        console.log(`缓存服务器数据: ${pathname}`);

        res.json(response.data);
    } catch (error) {
        console.error(`Proxy error for ${pathname}:`, error.message);
        res.status(error.response?.status || 500).json({
            error: error.message,
        });
    }
});

app.listen(PORT, () => {
    console.log(`Mock server is running on http://localhost:${PORT}`);
});

注: 代码有3个模式,根据自己需要调。
1:根据路径生成缓存文件。如:get请求分页页面,pageNo传1和2只缓存1次。
2:根据路径和get的query参数生成缓存文件。如:get请求分页页面,pageNo传1和2缓存2次。
3:根据路径和参数和post 请求生成缓存文件(会缓存较多文件)。

  1. 使用方式
    启动服务:
    bash
    node server.js
    现在你本地运行了一个监听 http://localhost:3000 的代理服务器。

浏览器或前端请求示例:
将原本请求的目标 URL 改成:
http://localhost:3000/api/xxx
在这里插入图片描述

第一次请求会从真实服务器获取数据并缓存为文件(如:mocks/_api_xxx.json),后续请求直接使用本地缓存。

缓存文件:
在这里插入图片描述


网站公告

今日签到

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