使用 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 为时已晚并获得为第二个用户准备的响应。
您可以通过
实现
- streaming 你的 HTML 内容和
- 使用 Content-disposition header 表示您想要下载文件
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}`);
});
我有一个快速应用程序,它在文件系统中生成一个 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 为时已晚并获得为第二个用户准备的响应。
您可以通过
实现- streaming 你的 HTML 内容和
- 使用 Content-disposition header 表示您想要下载文件
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}`);
});