资讯专栏INFORMATION COLUMN

从koa-static中间件学习搭建静态文件服务器

Olivia / 861人阅读

摘要:从中间件学习搭建静态文件服务器原文地址中有说明它只是的一个包装查看的源码可以发现,它做的工作是根据传入的查找文件是否存在,如果存在就创建一个流,不存在就抛出错误。

从koa-static中间件学习搭建静态文件服务器 原文地址 koa-send
Static file serving middleware

koa-static中有说明它只是koa-send的一个包装

const send = require("koa-send");

app.use(async (ctx) => {
  await send(ctx, ctx.path, { root: __dirname + "/public" });
})

查看koa-send的源码可以发现,它做的工作是根据传入的path查找文件是否存在,如果存在就创建一个流,不存在就抛出错误。

send函数可以传入第三个参数

maxage Browser cache max-age in milliseconds. (defaults to 0)

immutable Tell the browser the resource is immutable and can be cached indefinitely. (defaults to false)

hidden Allow transfer of hidden files. (defaults to false)

root Root directory to restrict file access.

index Name of the index file to serve automatically when visiting the root location. (defaults to none)

gzip Try to serve the gzipped version of a file automatically when gzip is supported by a client and if the requested file with .gz extension exists. (defaults to true).

brotli Try to serve the brotli version of a file automatically when brotli is supported by a client and if the requested file with .br extension exists. (defaults to true).

format If not false (defaults to true), format the path to serve static file servers and not require a trailing slash for directories, so that you can do both /directory and /directory/.

setHeaders Function to set custom headers on response.

extensions Try to match extensions from passed array to search for file when no extension is sufficed in URL. First found is served. (defaults to false)

可以看一下index的作用,事实上当我们在地址栏输入

http://www.aaa.com/
或者
http://www.aaa.com/index.html

可以发现效果是一样的,原因就是配置了index选项,服务端首先检查你的path是否以 "/" 结尾,假如你配置了index选项且以 "/" 结尾,那么服务端会自动将你的path和index选项拼接,如下:

const trailingSlash = path[path.length - 1] === "/"

...

if (index && trailingSlash) path += index

再看一下format的作用,其实我们经常在地址栏输入的是

http://www.aaa.com
而不是
http://www.aaa.com/

但他们的效果也是一样的,原因就是配置了format,经过resolve之后的path返回的是一个绝对路径,它是其中一种状态(文件或者文件夹),如果是文件夹,且设置了format(默认为true)和index,那么就自动添加index

    stats = await fs.stat(path)

    // Format the path to serve static file servers
    // and not require a trailing slash for directories,
    // so that you can do both `/directory` and `/directory/`
    if (stats.isDirectory()) {
      if (format && index) {
        path += "/" + index
        stats = await fs.stat(path)
      } else {
        return
      }
    }

extensions的作用好像不多见,比如你的a文件夹

| - a
    | - demo.txt
    | - demo.json
    | - demo.html

假如你设置了extensions(假设为["json", "txt"]),那么你在地址栏输入

http://www.aaa.com/a/demo

事实上等同于
http://www.aaa.com/a/demo.json

服务端会首先判断你是否设置了extensions且path不以 ".**" 结尾

  if (extensions && !/..*$/.exec(path)) {
    const list = [].concat(extensions)
    for (let i = 0; i < list.length; i++) {
      let ext = list[i]
      if (typeof ext !== "string") {
        throw new TypeError("option extensions must be array of strings or false")
      }
      // [".js"] 或者 ["js"] 均可以
      if (!/^./.exec(ext)) ext = "." + ext
      if (await fs.exists(path + ext)) {
        path = path + ext
        break
      }
    }
  }

然后按照extensions的顺序依次查找拼接的path是否存在,存在即停止查找

koa-static

koa-static的只是给koa-send包了一层,koa-send的第二个参数path是ctx.path

koa-static有个defer选项

defer If true, serves after return next(), allowing any downstream middleware to respond first.

  if (!opts.defer) {
    return async function serve (ctx, next) {
      let done = false

      if (ctx.method === "HEAD" || ctx.method === "GET") {
        try {
          // koa-send 输入的path不存在时抛错(404或者500)
          done = await send(ctx, ctx.path, opts)
        } catch (err) {
          // 如果错误码是404说明请求的不是静态文件
          if (err.status !== 404) {
            throw err
          }
        }
      }

      //  请求不是静态文件  继续执行下面的逻辑
      if (!done) {
        await next()
      }
    }
  }

  return async function serve (ctx, next) {
    await next()

    // 假如请求方法不是get  必然不是访问静态资源
    if (ctx.method !== "HEAD" && ctx.method !== "GET") return
    // 说明对请求已经做了响应
    if (ctx.body != null || ctx.status !== 404) return // eslint-disable-line

    try {
      await send(ctx, ctx.path, opts)
    } catch (err) {
      if (err.status !== 404) {
        throw err
      }
    }
  }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92091.html

相关文章

  • Koa-Static 该换换了吧 试试 Awesome-Static

    摘要:吼,所以我做了,和一样,都是对的一层封装,只不过用编写,对支持良好。 其实还是得按自个儿的需求来。 koa-static 有啥问题么 koa-static是一个非常轻量的koa中间件,能够迅速的搭建起一个静态文件服务器,通常我们把静态文件都放进public,并且通过类似koa-static这样的东西来将我们的public作为静态目录,这样的话,我们就能直接通过根路由进行访问了。 emm...

    kevin 评论0 收藏0
  • Koa-Static 该换换了吧 试试 Awesome-Static

    摘要:吼,所以我做了,和一样,都是对的一层封装,只不过用编写,对支持良好。 其实还是得按自个儿的需求来。 koa-static 有啥问题么 koa-static是一个非常轻量的koa中间件,能够迅速的搭建起一个静态文件服务器,通常我们把静态文件都放进public,并且通过类似koa-static这样的东西来将我们的public作为静态目录,这样的话,我们就能直接通过根路由进行访问了。 emm...

    CNZPH 评论0 收藏0
  • Node.js使用Koa搭建 基础项目

    摘要:目录一创建项目二配置路由三静态资源四模板引擎五结语是由原班人马打造的超轻量服务端框架与相比,除了自由度更高,可以自行引入中间件之外,更重要的是使用了,从而避免了回调地狱不过也是因为代码升级,所以需要以上的环境一创建项目手动创建一个项目目录, 目录 一、创建项目二、配置路由三、静态资源四、模板引擎五、结语 Koa 是由 Express 原班人马打造的超轻量服务端框架与 Express 相...

    BingqiChen 评论0 收藏0
  • Node.js使用Koa搭建 基础项目

    摘要:目录一创建项目二配置路由三静态资源四模板引擎五结语是由原班人马打造的超轻量服务端框架与相比,除了自由度更高,可以自行引入中间件之外,更重要的是使用了,从而避免了回调地狱不过也是因为代码升级,所以需要以上的环境一创建项目手动创建一个项目目录, 目录 一、创建项目二、配置路由三、静态资源四、模板引擎五、结语 Koa 是由 Express 原班人马打造的超轻量服务端框架与 Express 相...

    lewif 评论0 收藏0

发表评论

0条评论

Olivia

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<