Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

static file & koa-static #15

Open
brunoyang opened this issue Apr 21, 2016 · 2 comments
Open

static file & koa-static #15

brunoyang opened this issue Apr 21, 2016 · 2 comments

Comments

@brunoyang
Copy link
Owner

brunoyang commented Apr 21, 2016

用户访问我们的网站,得到的结果有两种,想看的和不想看的。

不想看的分两种,网站报错和地址输错。

想看的也分两种,动态生成和静态存在。今天,我们就来聊聊静态文件。

所谓静态文件

所谓的静态文件,就是静态的,static的文件,无需经过查找数据库、模板渲染等步骤(以上步骤为充分不必要)就可以直接给用户看的,如js、css文件,图片等。

一般来说,访问静态文件的url和其本身的文件路径是一样,如 http://a.com/public/img/a.png, 那目录下就会有个public文件夹。这是因为静态文件数量很可能非常庞大,不能给每个文件都加上路由,所以其文件路径就是url。

每个http响应头里都有Content-Type字段,该字段告诉浏览器返回的文件是什么类型的,便于浏览器处理。如一个html文件的Content-Type是text/html,而一般的文本文件Content-Type是text/plain,当把html文件的Content-Type改成text/plain,浏览器就不会解析html文件,而是直接输出html代码。我们可以通过文件的后缀识别该文件的MIME。

koa-static

有了上面的知识,我们再来看koa-static。基本用法如下代码:

'use strict';

const app = require('koa')();
const server = require('koa-static');

const opts = {
  maxage: 1000 * 60 * 60 * 24 * 365, // 1年,默认为0
  hidden: false, // 能否返回隐藏文件(以`.`打头),默认false不返回
  index: 'index.js', // 默认文件名
  defer: true, // 在yield* next之后返回静态文件,默认在之前
  gzip: true 
  // 允许传输gzip,如静态文件夹下有两个文件,index.js和index.js.gz,
  // 会优先传输index.js.gz,默认开启
};

app.use(server('/public', opts));

koa-static所做的,仅仅是简单地处理选项,真正干事的是koa-send模块,我们再来看看这个模块。

前面一段是选项处理,略过,看如下代码

if (encoding === 'gzip' && gzip && (yield fs.exists(path + '.gz'))) {
  path = path + '.gz';
  ctx.set('Content-Encoding', 'gzip');
  ctx.res.removeHeader('Content-Length');
}

如果开启了gzip选项,就会优先传输.gz文件。

if (stats.isDirectory()) {
  if (format && index) {
    path += '/' + index;
    stats = yield fs.stat(path);
  } else {
    return;
  }
}

若为目录,并且找不到index配置项的文件,直接return,如无意外就是404,不过这样情况是应该是403。另外,是否为隐藏文件的判断居然只是根据文件名前的.,完全不考虑windows机器。勇敢的少年快去提pr吧。

核心代码就是下面的几行

ctx.set('Content-Length', stats.size);
if (!ctx.response.get('Last-Modified')) {
  ctx.set('Last-Modified', stats.mtime.toUTCString());
}
if (!ctx.response.get('Cache-Control')) {
  ctx.set('Cache-Control', 'max-age=' + (maxage / 1000 | 0));
}
ctx.type = type(path);
ctx.body = fs.createReadStream(path);
@DarkFlame
Copy link

好 !!

@zaleGZL
Copy link

zaleGZL commented Nov 17, 2017

我使用了koa中的koa-static中间件来处理静态资源,可是为什么第二次请求相同的静态资源(资源未修改), 服务器返回的状态码不是304而是200?last-modified 和 if-modified-since 都正常发送了,我试了一下express就正常返回304,请问是设置的问题还是?

src

network

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants