使用grunt-connect处理图片路径

这问篇文章讲的东西,可能对于大部分前端开发同行中并不普遍有用。纯粹是由于我的一个强迫症,而去探索到的一个小“伎俩”。如果系统的学习过nodejs,这个知识点应该不在话下。

介绍下背景:

最近在开发一个移动端电商项目,前端采用AngularJS,使用Yeoman脚手架初始化项目,开发时使用grunt-connect启动服务,前后端高度分离,可以在grunt-connect的中间件配置中加入自己的逻辑,包括之前 使用Grunt-contrib-connect为html动态添加script标签 这篇谈到的动态添加script标签。既然是电商项目,肯定少不了大量的图片,并需要做不同尺寸的适配。前段时间后端处理好了同一图片的不同尺寸图片副本。在前端,根据需要,给原始图片路径地址添加不同的后缀即可获取不同尺寸的图片。但令我诧异的是,后端给我的后缀是这样的,比如:

1
2
3
4
http://img.xx.com/aa/bb/computer.jpeg!s6 //640x427
http://img.xx.com/aa/bb/computer.jpeg!s5 //150x100
//以此类推

都是以这种!sx 为后缀,虽然在集成进后端,这些地址不会404。又虽然可以用Angular的filter轻松实现,但是在前端开发环境,这些图片都会404(虽然开发环境的图片都是json硬编码),看着满页的空图片,了无声色,以及控制台的各种红色404,我的小心脏没几天就受不了了,遂研究之。

 

思考一下,有两种思路可以尝试:

1.重定向url,把!sx的后缀去掉,让客户端重新请求

2.直接分析url,如果是图片地址,则提取路径正确地址,读取服务器下的图片流返回

一开始,我以为在grunt-connect或grunt的api中能找到解决方案,但此路不通。后来注意到中间件提供的参数req,res,next,非常眼熟,在express中也很常用,再google之,其实它是nodejs底层的http模块的三个对象。终于在nodejs底层API找到了答案,在grunt-connect的中间件数组里,添加:

1
2
3
4
5
6
7
8
9
10
11
function (req, res, next) {//修正图片地址
var match = req.originalUrl.match(/!s\d$/);
if(match){
var imagePath = 'app' + req.originalUrl.replace(/!s\d$/,'');
var image = fs.readFileSync(imagePath);
res.writeHead(200, {'Content-Type': 'image/gif' });
res.end(image, 'binary');
return;
}
return next();
},

关键是第5,6,7行,读取本地图片,并以二进制流的形式返回给客户端.

Done!

有时候,强迫症也会带给你意外的收获。