koa 删除服务器文件,从koa-static中间件学习搭建静态文件服务器(示例代码)

从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

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值