【问题标题】:Merge, minify and serve JavaScript files with Express but the response is not gzipped使用 Express 合并、缩小和提供 JavaScript 文件,但响应未压缩
【发布时间】:2014-03-12 14:13:28
【问题描述】:

我正在使用 Express 构建一个 Web 应用程序。我想合并、缩小和提供 .js 文件。我写了一个中间件,这是我的代码:

var fs = require('fs'),
    path = require('path'),
    uglify = require('uglify-js'),
    cache = '',
    scriptsDir = path.join(__dirname, '../scripts'),
    files = fs.readdirSync(scriptsDir);

// Sync read is not a problem since the following code is executed on startup
files.forEach(function(fname) {
    if (/^.*\.js$/.test(fname)) {
        cache += fs.readFileSync(path.join(scriptsDir, fname), 'utf8').toString();
    }
});
cache = uglify.minify(cache, { fromString: true }).code;

module.exports = function(req, res, next) {
    if (req.url === '/js/all.js')
        res.end(cache);
    else
        next();
};

中间件是这样使用的:

app.use(compress());
[...]
app.use(app.router);
app.use(jsMerger); // Here is my middleware
app.use(express.static(path.join(__dirname, '../public')));

问题是响应没有被压缩。此外,响应中有“没有标头”(我的意思是,没有缓存标头,没有 etag;static 中间件提供的其他资源具有这些标头)。这是回应:

X-Powered-By: Express
Transfer-Encoding: chunked
Date: Wed, 12 Mar 2014 14:04:19 GMT
Connection: keep-alive

我错过了什么吗?如何压缩响应?

【问题讨论】:

标签: javascript node.js express gzip middleware


【解决方案1】:

在添加res.set('Content-Type', 'text/javascript') 行后,Express 正在压缩响应。代码是

module.exports = function(req, res, next) {
    if (req.url === '/js/all.js') {
        res.set('Content-Type', 'text/javascript');
        res.end(cache);
    } else {
        next();
    }
};

现在响应的标题是:

X-Powered-By: Express
Vary: Accept-Encoding
Transfer-Encoding: chunked
Date: Wed, 12 Mar 2014 14:45:45 GMT
Content-Type: text/javascript
Content-Encoding: gzip
Connection: keep-alive

原因在于compress 中间件的设计方式。您可以为compress 提供filter 选项:

app.use(express.compress({
    filter : function(req, res) {
        return /json|text|javascript/.test(res.getHeader('Content-Type'));
    }
});

压缩仅应用于与过滤器匹配的请求。的默认过滤器是:

function(req, res){
    return /json|text|javascript|dart|image\/svg\+xml|application\/x-font-ttf|application\/vnd\.ms-opentype|application\/vnd\.ms-fontobject/.test(res.getHeader('Content-Type'));
};

如果您不提供 Content-Type 标头,则请求将不会通过过滤器,并且 express 不会压缩响应。

【讨论】:

    最近更新 更多