NGINX+NJS应用场景之 带内容预览功能的文件服务器
2020-04-09 16:20:57
宗兆伟
NJS旨在成为NGINX的通用脚本框架。
NJS允许用户用脚本的方式给复杂业务场景下的流量负载添加处理逻辑。
它是扩展NGINX 应用的一把利刃。
编者注:
文本所涉及源码均可通过访问以下github 代码仓库获得。
https://github.com/zongzw-nginx/nginx-njs-usecases
本文用例是使用NGINX和NJS构建一个带内容预览功能的文件服务器。
通过此用例演示NJS 基本指令的使用方法,展示其是如何与NGINX相关指令配合实现更丰富文件内容展现形式的。
一、需求定义
我们知道NGINX提供的autoindex 功能可以帮助我们实现一个简单的内容服务器。
类似如下所示:
另外也可以通过配置autoindex_format json; 以json格式得到目录的信息:
在不借助第三方专门的文件服务器逻辑的情况下,NGINX的文件服务器能否以更丰富更炫的方式展示以上文件列表,更形象的展示文件的类型、大小、名称等等,就像照片墙一样供我们预览。
最终的展示效果为:
如上图所示,展示特点为:
- 文件类型以图标方式形象展示:文本、文档、视频、音频、压缩文件等。
- 如果图片则直接显示图片本身的缩略图。
- 以表格方式排布,列数依据浏览器宽度自适应。
答案是肯定的,本文实现了这种方式。
我们共需要用到以下技术:
- NGINX配置指令:autoindex;
- NJS 模块指令:js_include js_content js_set
- NJS JavaScript:JSON subrequest
- HTML CSS 定义基本显示样式
接下来我们按照请求应答的逻辑过程逐步分析代码的各个部分。
二、源码实现
先看下源文件列表:
1.当我们访问 http://localhost:8091/prev/ 时
除了/prev/,NGINX配置文件中还有2个暴露的API:
- /json/: 显示json格式的文件列表。
- /html/:显示html格式的文件列表。
当访问/prev/时,NGINX会匹配到 /prev/的location,http请求的后续处理交由js_content preview 处理。
2.preview调用subrequest 获取文件信息json
从preview的实现看,首先preview先通过用户访问的r.uri获取实际的访问路径,然后用这个path subrequest的方式访问 /json${path}, /json/ location的实现如下:
其中autoindex_format 定义为json,当访问/json/xxx 时,以json的格式返回文件信息。
当preview得到json信息后,对文件信息进行分析加工。
NJS使用JSON.parse(r.responseBody)的方式将子请求返回解析为json格式。
从前边json返回包体的截图中可以看到,数组中每个元素包含有文件名大小,类型等信息。
我们可以通过文件的后缀和mime.types的组合判断文件的类型。预定义的类型匹配在preview.js mime_map 变量中:
实现从mime.type 到 类型 映射的函数为:
3. 设置显示样式
为了更清晰的显示文件列表,我们定义了几个css样式:
其中 每个文件的显示大小和图片大小可以通过参数的方式传入。处理显示大小的变量和函数定义如下:
可以看到,页面的显示比例是参数化的,可配置的。
同时,要注意到,nginx.conf文件中预览图示的大小 也是通过get_image_width 和get_image_height 函数获取的:
4.组装html报文
使用get_div_body组装http报文的逻辑如下:
通过判断item.type 和 mime.types对类型的映射,我们配置不同的变量,这五个变量会嵌入到<div></div>中,显示在html页面上。
至此,实现部分的分析完成。
NJS可以帮助我们做很多事情。
本文提到的带阅览功能的文件服务器的实现只是一种展示,通过NJS的脚本处理,它可以高效的和NGINX的指令配合使用完美处理我们的需求。
发布评论 加入社群
相关文章

博文精选 | 对话中国移动:支撑数亿用户的基础设施如何实施云原生改造?
F5小安
2021-12-27 10:58:54 381

博文精选 | 对话中国移动:支撑数亿用户的基础设施如何实施云原生改造?
F5小安
2021-12-27 10:58:53 406

NGINX+NJS应用场景之 PASV模式下FTP ALG协议支持
宗兆伟
2020-04-13 13:58:45 1825

回复评论
发布评论