静态资源

¥Static Assets

提供静态资源,例如 HTML、图片、CSS、JavaScript 等。

¥Serve static assets such as HTML, images, CSS, JavaScript, etc.

H3 可以提供静态资源,例如 HTML、图片、CSS、JavaScript 等。

¥H3 can serve static assets such as HTML, images, CSS, JavaScript, etc.

要提供静态目录,你可以使用 serveStatic 实用程序。

¥To serve a static directory, you can use the serveStatic utility.

import { H3, serveStatic } from "h3";

const app = new H3();

app.use("/public/**", (event) => {
  return serveStatic(event, {
    getContents: (id) => {
      // TODO
    },
    getMeta: (id) => {
      // TODO
    },
  });
});

目前尚不支持任何文件。你需要实现 getContentsgetMeta 方法。

¥This does not serve any files yet. You need to implement the getContents and getMeta methods.

  • getContents 用于读取文件的内容。它应该返回解析为文件内容的 Promise,如果文件不存在,则返回 undefined
  • getMeta 用于获取文件的元数据。它应该返回解析为文件元数据的 Promise,如果文件不存在则返回 undefined

它们被分开,以便 H3 无需读取文件内容即可响应 HEAD 请求,并使用 Last-Modified 标头。

¥They are separated to allow H3 to respond to HEAD requests without reading the contents of the file and to use the Last-Modified header.

读取文件

¥Read files

现在,在 public 目录中创建一个包含简单消息的 index.html 文件,然后打开浏览器访问 http://localhost:3000。你应该看到以下消息。

¥Now, create a index.html file in the public directory with a simple message and open your browser to http://localhost:3000. You should see the message.

然后,我们可以创建 getContentsgetMeta 方法:

¥Then, we can create the getContents and getMeta methods:

import { stat, readFile } from "node:fs/promises";
import { join } from "node:path";
import { H3, serve, serveStatic } from "h3";

const app = new H3();

app.use("/public/**", (event) => {
  return serveStatic(event, {
    indexNames: ["/index.html"],
    getContents: (id) => readFile(join("public", id)),
    getMeta: async (id) => {
      const stats = await stat(join("public", id)).catch(() => {});
      if (stats?.isFile()) {
        return {
          size: stats.size,
          mtime: stats.mtimeMs,
        };
      }
    },
  });
});

serve(app);

getContents 读取文件并返回其内容,非常简单。getMeta 使用 fs.stat 获取文件元数据。如果文件不存在或不是文件,则返回 undefined。否则,它将返回文件大小和最后修改时间。

¥The getContents read the file and returns its contents, pretty simple. The getMeta uses fs.stat to get the file metadata. If the file does not exist or is not a file, it returns undefined. Otherwise, it returns the file size and the last modification time.

如果文件自上次请求以来未被修改,则使用文件大小和上次修改时间创建一个 etag 来发送 304 Not Modified 响应。如果文件未发生更改,这可以避免多次发送相同的文件。

¥The file size and last modification time are used to create an etag to send a 304 Not Modified response if the file has not been modified since the last request. This is useful to avoid sending the same file multiple times if it has not changed.