使用 Node/Express 创建并下载 html 文件而不将其保存在文件系统中

Create and download html file without saving it in filesystem with Node/Express

我有一个快速应用程序,它在文件系统中生成一个 HTML 文件,然后下载它。 https://node-page-generator.herokuapp.com/

有没有什么方法可以创建和下载文件而不依赖于文件系统来保存和检索文件?

该应用使用 fs.writefile():

import fs from 'fs';

export const callFileSystem = (path: string, content:string) => {
  fs.writeFile(
    `${path}`,
    `${content}`,
    function (err: any) {
      if (err) throw err;
      console.log('file created');
    }
  )
}

POST /generate 上的 HTTP 请求将所有页面属性发送到创建 index.html 文件的 generatePage 函数

import { pageProperties } from './pageProps';
import { callFileSystem } from '../../helpers/fileSystem';

export const generatePage = (props: pageProperties) => {
  const path = 'index.html';

  callFileSystem(
    path,
    `
  <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <link rel="icon" href="${props.logoUrl}" type="image">
            <title>${props.title}</title>
            <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
        </head>
        <body>
            <style>
                :root {
                    --navbar-color: ${props.navbar.backgroundColor};
                    --background-color: ${props.pageBackgroundColor};
                    --font-color: ${props.fontColor};
                }
                html, body, h1, h2 {
                    margin: 0;
                }
                h1, h2, h3, h4, h5, p, span {
                    text-align: center;
                    color: var(--font-color, title, logoUrl, cardContent);
                }
                html {
                    margin: 0;
                    padding: 0;
                }
                body {
                    margin: 0;
                    padding: 0;
                    background-color: var(--background-color, title, logoUrl, cardContent);             
                }
                .navbar {
                    background-color: var(--navbar-color, title, logoUrl, cardContent) !important;                
                }
            </style>
    
    <nav class="navbar navbar-light navbar-bg">
        <div class="container">
          <a class="navbar-brand" href="#">
            <img src="${props.logoUrl}" alt="" width="30" height="24">
            <h1>${props.title}</h1>
          </a>
        </div>
      </nav>     
      <div class="main container d-flex justify-content-center ">
    
      </div>       
        </body>
        </html>
  `
  );
}

然后 /download 的 GET 请求下载生成的文件:

export const downloadPage = (response: Resp) => {
  const file = 'index.html';
  response.download(file);
}

我尝试调用 fs.writefile() 作为 res.download() 的路径参数,但没有成功。

虽然应用程序按预期工作,但此方法的问题是,如果两个 /generate 请求大致同时发出,第一个用户可能会调用 /download 为时已晚并获得为第二个用户准备的响应。

您可以通过

实现
const stream = require("stream");
const express = require("express");
const app = express();
const port = 3000;

const htmlString = `
<!DOCTYPE html>
<html lang="en">
   <head>
      <title>My Title</title>
   </head>
   <body>My HTML Content</body>
</html>`;

app.get("/", (req, res) => {
  const readStream = new stream.PassThrough();
  readStream.end(htmlString);

  res.set("Content-disposition", "attachment; filename=index.html");
  readStream.pipe(res);
});

app.listen(port, () => {
  console.log(`App listening on port ${port}`);
});