You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js删除目录旧文件、生成PHP文件打包下载功能异常问题咨询

Node.js批量生成PHP文件并打包下载的时序问题修复方案

问题核心原因

你遇到的问题本质是异步IO操作的时序错误,主要有以下几个错误点:

  • 调用generatePHPFiles和createZipFile两个异步函数时未加await,导致操作未完成就提前执行下载逻辑
  • 封装的Promise未等待所有fs异步写入操作完成就提前resolve,实际文件还没写入磁盘
  • 压缩包生成逻辑错误,每添加一个文件就写一次压缩包,应该全部添加完成后再统一生成
  • 关键词空格替换仅替换了第一个空格,多空格关键词会生成异常文件名
  • 原代码漏引入express依赖,且全局挂载了业务中间件,所有请求都会触发文件删除逻辑

修复方案

优化思路

  1. 替换回调式fs API为Node.js官方自带的Promise版本fs,无需手动封装Promise降低出错概率
  2. 所有异步操作加await等待执行完成后再进入下一步
  3. 修正压缩包生成逻辑,全部文件添加完成后再统一输出压缩包
  4. 修正空格替换逻辑为全局正则替换,适配多空格关键词场景
  5. 将业务中间件绑定到指定路由,避免误触发逻辑

修复后完整代码

const fs = require("fs/promises");
const path = require("path");
const axios = require("axios");
const cheerio = require("cheerio");
const zipadm = require("adm-zip");
const express = require('express');
// 初始化应用
const app = express();
// 解析表单参数
app.use(express.urlencoded({ extended: false }))
// 配置端口
const PORT = 8000;
// 工具函数
async function deletePreviousFiles() {
    const files = await fs.readdir(__dirname);
    for (const file of files) {
        if (file.includes(".php") || file.includes("sitemap.txt") || file.includes(".zip")) {
            await fs.unlink(path.join(__dirname, file));
        }
    }
}
async function generateSitemapFile(webpage, words) {
    const keywords = words.split(",");
    let sitemapContent = '';
    for (let i = 0; i < keywords.length; i++) {
        let fileName = keywords[i].trim().replace(/\s+/g, "_");
        let newLink = `${webpage}${fileName}.php`;
        sitemapContent += `${newLink}\n`;
    }
    await fs.writeFile(`sitemap.txt`, sitemapContent);
}
async function generatePHPFiles(data, words) {
    const $ = data;
    const htmlContent = $.html();
    const keywords = words.split(",");
    const writeTasks = keywords.map(keyword => {
        let fileName = keyword.trim().replace(/\s+/g, "_");
        return fs.writeFile(`${fileName}.php`, htmlContent);
    })
    await Promise.all(writeTasks);
}
async function createZipFile() {
    const zip = new zipadm();
    const files = await fs.readdir(__dirname);
    for (const file of files) {
        if (file.includes(".php") || file.includes("sitemap.txt")) {
            zip.addLocalFile(path.join(__dirname, file));
        }
    }
    zip.writeZip(path.join(__dirname, "NewPhpFiles.zip"));
}
// 业务逻辑中间件
const startApplication = async (req, res, next) => {
    try {
        const webPageLink = req.body.link;
        const seoKeywords = req.body.keywords;        
        await deletePreviousFiles();
        console.log("旧文件已删除...");
        await generateSitemapFile(webPageLink, seoKeywords);
        console.log("站点地图已生成...");
        let response = await axios.get(webPageLink);
        const data = cheerio.load(response.data);
        console.log("网页内容已加载...")
        await generatePHPFiles(data, seoKeywords);
        console.log("PHP文件已生成...")
        await createZipFile();
        console.log("压缩包已生成...")     
        next();
    } catch (error) {
        console.log(error)
        res.status(500).send('服务处理出错,请重试')
    }
}
// 下载逻辑
const downloadFile = async (req,res) => {
    try {
        res.download(path.join(__dirname, "NewPhpFiles.zip"), (err) => {
            if(err) {
                res.status(500).send('文件下载失败')
            }
        });
    } catch (error) {
        console.log(error)
        res.status(500).send('文件下载失败')
    }
}
// 路由绑定
app.post("/submit", startApplication, downloadFile)
// 启动服务
app.listen(PORT, console.log(`应用已启动,监听端口:${PORT}...`));

内容的提问来源于stack exchange,提问作者Hamza Imranist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 01:15:02