问题
在引入第三方中间件之前,我们在使用 koa
时,可能像下面这样来引入静态资源:
app.use(ctx => {
const url = ctx.url == '/' ? '/index.html' : ctx.url
const fileType = path.extname( url ).slice(1);
if (fileType ==='html') {
ctx.response.type = 'html';
ctx.response.body = fs.createReadStream('index.html');
} else if (fileType ==='css') {
ctx.response.type = 'css';
ctx.response.body = fs.createReadStream('index.css');
} else if (fileType ==='jpg') {
ctx.response.type = 'image/jpg';
ctx.response.body = fs.createReadStream('skills.jpg');
} else {
ctx.response.body = '文件不存在';
}
});
显然,在实际工作中,如果所有功能都需要自己去实现的话,效率会很低,不仅会延迟,还会有很多未知的bug。有没有更好的方式呢?
方案
在这里, 我们引入Koa静态文件服务中间件,Koa -send的包装器——koa-static
安装
npm install koa-static
使用Koa的框架、样板和其他入门套件:
Home · koajs/koa Wiki · GitHub
API
import Koa from 'koa'; // CJS: require('koa');
import staticServe from 'koa-static'; // CJS: require('koa-static')
const app = new Koa();
app.use(staticServe(root, opts));
root
根目录字符串。不能为这个根目录以上的目录提供服务。opts
选项(对象)。
选项
maxage
浏览器最大缓存时间(毫秒)。默认值为0hidden
允许传输隐藏的文件。默认值为falseindex
默认文件名,默认为’index.html’defer
如果为true,则在返回next()之后服务,允许任何下游中间件首先响应。gzip
如果客户端支持gzip,并且请求的扩展名为.gz的文件存在,尝试自动提供gzip版本的文件。默认值为true。brotli
如果客户端支持brotli,并且请求的文件扩展名为.br(注意,该brotli只能通过https接受),则尝试自动提供brotli版本的文件。默认值为true。
setHeaders
函数设置响应的自定义标头。extensions
尝试从传递的数组匹配扩展名搜索文件时,没有扩展名是足够的URL。先找到就给。(默认值为false)
示例
// app.js
const path = require('path');
const Koa = require('koa');
const staticServe = require('koa-static');
const app = new Koa();
const staticPath = '/static';
const absolutePath = path.join(__dirname + staticPath);
console.log(absolutePath);
app.use(staticServe(absolutePath)); // 可以指定多个静态目录
app.use(async (ctx) => {
ctx.body = 'hello word'
});
app.listen(3000);
console.log('listening on port 3000');
例如,访问 /static/静态文件名 时不需要加上static,即 http://127.0.0.1:3000/静态文件名 这种形式即可访问。