使用 ExpressJS Typescript NodeJS 提供静态文件

J0r*_*dAn 1 node.js express typescript

我试图通过 Typescript 提供使用 ExpressJS 和 NodeJS 上传的静态文件,但出现 404 错误。

我想读取的文件是 ./src/data/uploads/test.txt 我试图直接从网络浏览器访问它。

注意:当我在 Javascript 中执行此操作时,它有效,但在 Typscript 中无效。

index.ts 文件(应用程序入口点)

import express from 'express';
import bodyParser from 'body-parser';
import helmet from 'helmet';
import {cdg, config} from './utils';
import {Mongoose} from './db/monogdb';
import { setRoutes } from './routes/route.decorators';
import cors from 'cors';
import './routes';

const app = express();

app.use(helmet());
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/ftp', express.static('data/uploads'));

setRoutes(app);

app.listen(config.server.port, () => {
    cdg.konsole("Server connected! :: " + config.server.port + "!");
});

Run Code Online (Sandbox Code Playgroud)

有没有一种特定的方法可以使用 Typescript 提供静态文件?

jfr*_*d00 7

工作原理如下express.static()。您显然缺少其中一个步骤,但您的问题缺乏详细信息来准确确定哪个步骤不正确。

首先,定义一个express.static()包含一些参数的中间件。就您而言,您已经定义了:

app.use('/ftp', express.static('data/uploads'));
Run Code Online (Sandbox Code Playgroud)

有四个要素决定其工作原理:

  1. 必须/ftp位于任何 URL 的开头,此中间件才能匹配。
  2. 传入的 URL 请求以及浏览器如何根据您在 HTML 中指定的方式形成该请求。
  3. 当前工作目录与 组合起来data/uploads形成完整路径引用,或者您可以构建自己的绝对路径而不依赖于 cwd。
  4. cwd + /data/uploads其中的文件express.static()将尝试与传入 URL 的路径匹配。

让我们进一步研究这些:

您的中间件首先只会查看以/ftp. 然后,对于它看到的任何以 开头的 URL /ftp,它应该获取 URL 的其余部分并将其附加到data/uploads并查看它在本地文件系统中找到匹配的文件。它将在请求时使用服务器进程中的当前工作目录来尝试解析相对路径data/uploads。当前工作目录(如果您没有以编程方式更改它)将取决于您的应用程序的启动方式。

因此,如果您使用 启动应用程序node index.js,那么当前工作目录将是所在目录,并且 Express static 将在“index.js”所在的子目录中index.js查找。data/uploads

然后,我们需要看看指定这个静态资源的HTML标签是如何指定的。

<img>例如,假设这是一个标签。如果您指定这样的内容:

 <img src="/ftp/hello.jpg">
Run Code Online (Sandbox Code Playgroud)

然后,浏览器将向您的服务器创建一个请求/ftp/hello.jpg。由于确实以 开头/ftp,因此您的express.static()中间件将采用路径的其余部分/hello.jpg并将其附加到data/uploads并构建一个如下所示的路径:

path.join(process.cwd(), 'data/uploads', '/hello.jpg')
Run Code Online (Sandbox Code Playgroud)

并且,它将在本地文件系统中查找生成的文件。如果它找到该文件,那么它将提供该文件并将其作为响应返回。如果它没有找到确切的文件,那么它将调用next()并继续路由到其他路由处理程序。

有许多常见错误(可能会出错的事情):

  1. 您没有在网页中指定与express.static()中间件行一致的正确 URL(包括/ftp中间件指定的前缀)。

  2. 您的中间件并未完全指向文件系统中的正确目录,因此它永远找不到任何内容。

  3. 您在网页中使用相对 URL,浏览器将其与网页路径相结合,导致它请求与您想要的不同的内容。网页中的静态资源 URL 几乎总是以 开头,/因此它们不依赖于父页面的路径。

  4. 这些文件在您使用中间件指向的文件层次结构中的位置不太正确(通常会偏离一级)。


我要提到的另一件事。由于您使用的是 TypeScript,这意味着您必须将脚本编译/构建为常规 .js 脚本,然后才能运行。这通常位于不同的目录位置。

这种不同的目录位置使您有机会不引用静态资源所在的正确目录,因为它们可能相对于您的 TypeScript 文件而不是您正在运行的构建的 Javascript 文件定位(这取决于您的构建脚本) 。

同样,如果您向我们展示文件系统中所有内容(TypeScript 文件、内置 JS 文件、静态资源)的位置以及引用静态资源的 HTML 标记是什么样子,我们可以帮助您更具体地进行调试。

  • @Couranos - 您必须从文件所在的任何位置提供文件,并且必须将“express.static()”指向它们所在的目录。因此,您可以将文件复制到构建脚本中指向的位置,也可以更改“express.static()”查找它们的位置。选一个。 (2认同)