Node.js 项目 TypeScript + express 实现 Web 服务端返回文件内容

TypeScript 实现 Web 服务端返回文件内容

基于已搭建的 TypeScript 开发环境,我们可以快速实现一个 Web 服务端应用,通过 GET 请求接收文件名参数,并返回对应文件的内容。以下是具体实现步骤和代码。

一、添加 HTTP 服务依赖

Node.js 内置了http模块可用于创建 Web 服务,但为了简化开发,我们使用更友好的express框架(需安装类型定义):

bash 复制代码
mkdir ts-file-server && cd ts-file-server
npm init -y  # 生成 package.json

# Express(Web 框架)
npm install express --save
# CORS 中间件(解决跨域问题,可选但推荐)
npm install cors --save
# TypeScript 类型定义(让 TS 识别 Express、Node.js API)
npm install @types/express @types/cors @types/node --save-dev
# TypeScript 编译器
npm install typescript --save-dev

配置 tsconfig.json

在项目根目录创建 tsconfig.json,确保 TS 编译选项正确:

json 复制代码
{
  "compilerOptions": {
    "target": "ES2020",          // 目标 JS 版本(Node.js 14+ 支持)
    "module": "ES2022",          // 模块系统(Node.js 用 # ES Module)
    "moduleResolution": "node",
    "outDir": "./dist",          // 编译输出目录(TS → JS 存放于此)
    "rootDir": "./src",          // 源码根目录(TS 文件存放于此)
    "skipLibCheck": true,        // 跳过第三方库类型检查(提升速度)
    "allowSyntheticDefaultImports": true,
    "strict": true               // 严格类型检查(推荐开启)
  },
  "include": ["src/**/*"],       // 需要编译的文件(src 目录下所有 TS 文件)
  "exclude": ["node_modules"]    // 排除 node_modules 目录
}

二、编写 Web 服务代码

在src目录下创建 app.ts 文件,实现接收 GET 请求并返回文件内容的功能:

javascript 复制代码
import express, { Request, Response } from 'express';
import cors from 'cors';
import fs from 'fs/promises'; // 使用 Promise 风格的 fs 模块(异步非阻塞)
import path from 'path';      // 处理文件路径(跨平台兼容)

// 初始化 Express 应用
const app = express();
const port = 3000; // 服务器端口(可自定义)

// 中间件:解决跨域问题(前端调用时需要)
app.use(cors());

// 中间件:解析 URL 参数(获取 GET 请求中的文件名)
app.use(express.urlencoded({ extended: true }));

import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

console.log('当前文件路径:', __filename);
console.log('当前文件所在目录:', __dirname);

const FILES_DIR = path.resolve(__dirname, '../');
console.log('FILES_DIR=', FILES_DIR);

/**
 * GET 请求处理:读取文件内容并返回
 * 路由:/file?name=文件名(如 /file?name=example.txt)
 */
app.get('/file', async (req: Request, res: Response) => {
  try {
    // 1. 从请求参数中获取文件名(需校验是否存在)
    const fileName = req.query.name?.toString();
    console.log(`fileName=${fileName}=`)
    if (!fileName) {
      return res.status(400).send('请提供文件名(参数名:name)');
    }

    // 2. 定义文件存储路径(避免目录遍历攻击,限制在 ./files 目录下)
    const safePath = path.join(FILES_DIR, 'files', fileName);
    console.log(`safePath=${safePath}=`)
    // 校验路径是否合法(防止用户传入 ../ 等越界路径)
    if (!safePath.startsWith(path.join(FILES_DIR, 'files'))) {
      return res.status(403).send('非法文件路径');
    }

    // 3. 异步读取文件内容(使用 fs.promises.readFile)
    const fileContent = await fs.readFile(safePath, 'utf-8');

    // 4. 返回文件内容(设置 Content-Type 为文本)
    res.set('Content-Type', 'text/plain');
    res.send(fileContent);

  } catch (err) {
    // 处理文件不存在、权限不足等错误
    if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {
      res.status(404).send('文件不存在');
    } else {
      res.status(500).send('服务器内部错误');
    }
  }
});

// 启动服务器
app.listen(port, () => {
  console.log(`文件服务已启动,访问 http://localhost:${port}/file?name=example.txt`);
});

三、准备测试文件

  1. 在项目根目录创建files文件夹(与src同级):
arduino 复制代码
mkdir files
  1. 在files目录下创建测试文件(如example.txt),写入内容:

    这是测试文件1的内容
    来自TypeScript Web服务

四、编译并运行服务

  1. 编译 TypeScript 代码

    npx tsc

编译后会在dist/src目录生成server.js。

  1. 启动 Web 服务
bash 复制代码
node dist/src/server.js

终端会输出:

bash 复制代码
文件服务已启动,访问 http://localhost:3000/file?name=example.txt

五、测试服务

  1. 打开浏览器或使用 curl 工具访问:
bash 复制代码
http://localhost:3000/file?name=example.txt
  1. 成功时会显示example.txt的内容:

    这是测试文件1的内容
    来自TypeScript Web服务

  2. 测试错误场景:

六、代码说明

  1. 安全处理
    • 使用join和resolve拼接路径,限制文件只能从files目录读取,防止路径遍历攻击(如?name=../secret.txt)。
    • 对请求参数进行验证,确保文件名存在。
  1. HTTP 响应
    • 成功时返回 200 状态码和文件内容,设置Content-Type为text/plain确保中文正常显示。
    • 错误时返回对应状态码(400 参数错误、404 文件不存在)。
  1. 异步处理
    • 使用async/await处理文件读取的异步操作,代码更简洁。

七、扩展方向

  1. 支持更多文件类型(如图片、JSON),通过文件后缀自动设置Content-Type。
  1. 添加缓存机制,避免频繁读取相同文件。
  1. 限制文件大小和访问权限,增强安全性。

通过这个示例,你可以理解如何在 TypeScript 中结合 Node.js 创建 Web 服务,并实现文件读取与 HTTP 响应的完整流程。

相关推荐
用户66982061129824 分钟前
js今日理解 blob和arrayBuffer 二进制数据
前端·javascript
1024小神13 分钟前
Ant Design这个日期选择组件最大值最小值的坑
前端·javascript
安禅不必须山水1 小时前
Javascript函数里的this指向
javascript
拉不动的猪1 小时前
移动端音频插件howler简单配置
前端·javascript·vue.js
_一两风2 小时前
《告别回调地狱!三种写法带你玩转 JavaScript 异步》
javascript·ecmascript 6
林太白2 小时前
Rust-导入导出
前端·javascript·后端
_Kayo_3 小时前
JS深拷贝 浅拷贝、CSS垂直水平居中
开发语言·前端·javascript
碎像3 小时前
uni-app实战教程 从0到1开发 画图软件 (学会画图)
前端·javascript·css·程序人生·uni-app
Hilaku4 小时前
从“高级”到“资深”,我卡了两年和我的思考
前端·javascript·面试