本文将会介绍如何使用 Docker、Node、JavaScript、Traefik 完成一个简单的目录索引服务,全部代码在 300 行以内。相关代码已开源至 GitHub ,文末有链接,感兴趣可以自取。

实现一个目录索引站点并不是什么难事,但是即便如此,需要考虑的事情也有很多,要实现非阻塞IO、要实现文件缓存、要实现SSL等等一系列稍微有些麻烦的事情,如何能在尽可能少编写代码的情况下,完成这个需求呢。

其实很简单,借助完善靠谱的开源项目们,本文最终实现例子效果如下。

最终结果预览

实现核心逻辑

说到 Web 目录索引服务,我们一般会想到的就是大名鼎鼎的 Nginx 或者它的竞品们了。而它其中一个默认模块便提供了这个目录列表的功能: ngx_http_autoindex_module。

这个模块十分简单,在此我就不过度展开,有兴趣可以翻阅 Nginx 官方文档,了解这个模块提供的几个简单的指令。

对某个路由下的页面开启 autoIndex 可以轻松实现列目录的功能,比如这样:

location / {

autoindex_format html;

autoindex_localtime on;

autoindex_exact_size on;

autoindex on;

}

如果你简单使用上面的逻辑,你会得到一个黑底白字的页面,虽然能用,但是未免太过丑陋,查看生成文档源代码(由于代码高亮问题,使用 xpre 代替 pre):

Index of /

Index of /


../

a/ 16-Dec-2018 13:39 -

b/ 16-Dec-2018 13:39 -

c/ 16-Dec-2018 13:39 -


这个时候一般会有两个方案对默认的界面进行美化:

  1. 编译一个支持定义模板的 Nginx 插件。
  2. 使用 ngx_http_addition_module 模块手动进行模板美化。

第一种方案需要额外编译,有一定的额外维护成本、以及后续升级改造的不稳定因素。我们选择第二种方式,比如将上面的逻辑改造为:

location / {

add_before_body /autoindex/header.html;

add_after_body /autoindex/footer.html;

autoindex_format html;

autoindex_localtime on;

autoindex_exact_size on;

autoindex on;

}

代码生效后,你将得到这样的文档结果:

小站Index of /

Index of /


../

a/ 16-Dec-2018 13:39 -

b/ 16-Dec-2018 13:39 -

c/ 16-Dec-2018 13:39 -


这时你会发现样式似乎是正常了,但是会出现三个额外的问题:

  1. 文档闭合不标准,存在多个文档闭合标签。
  2. Nginx AutoIndex 默认生成的 HTML 文档存在内联样式标签,无法像三方模块一样进行页面定制。
  3. 默认生成文档结构不利于SEO以及不利于页面样式定制。

但是很庆幸,Nginx 还提供了一个内置模块:ngx_http_sub_module。 这个模块拥有编程语言中 replace 函数的作用,配合少量的替换操作,我们可以将文档轻松改造成我们想要的结构。

location / {

add_before_body /autoindex/header.html;

add_after_body /autoindex/footer.html;

autoindex_format html;

autoindex_localtime on;

autoindex_exact_size on;

autoindex on;

sub_filter '

Index of $uri' '';

sub_filter '

' '';

sub_filter '' '';

sub_filter '


' '';

sub_filter '


' '';

sub_filter '' '';

sub_filter_once on;

charset utf-8;

}

此刻,再查看文档,会发现文档已经十分适合进行样式改造了。

小站

Index of /

../

a/ 16-Dec-2018 13:39 -

b/ 16-Dec-2018 13:39 -

c/ 16-Dec-2018 13:39 -

在有一个良好的文档基础之后,我们可以使用 JavaScript 对它进行简单的增强,考虑到最基础浏览器的兼容问题,我们使用 ES5 标准进行逻辑书写,下面不到二十行的代码,可以让我们使用文档中的 pre 标签作为数据源,重新生成适合排版的模板。

var dataSets = document.getElementsByTagName('pre')[0].innerHTML.split('');

var directoryUp = false;

var tpl = '';

for (var i = 0, j = dataSets.length - 1; i < j; i++) {

var line = dataSets[i];

if (line.indexOf('../') === -1) {

line = line.match(/^(.*)s+(S+sS+)s+(S+)/);

tpl += '

' +

'

' + line[1] + '' +

'

' + '' + line[2] + '' + '' +

'

' + line[3] + '' +

'

';

} else {

if (location.pathname !== '/') directoryUp = true;

}

}

if (directoryUp) tpl = '

..' + tpl;

document.getElementsByTagName('tbody')[0].innerHTML = tpl;

当然,如果你想拥有更适合阅读的时间戳,可以引入一个名为 timeago.js 的脚本,配合下面的代码,让 Nginx 输出的时间戳变可读性变的更好。

timeago().render(document.querySelectorAll('.date'));

借助容器快速服务化

因为我们并未对 Nginx 进行任何改造,所以我们可以很省事的直接使用 Nginx 官方镜像提供我们的目录索引服务,这里推荐使用 alpine 镜像,小巧好用,比如下面的镜像,连带系统到软件,不到 20 MB

nginx:1.15.7-alpine

为了简单,我直接使用 compose 和 Traefik 完成搭建应用的最后一步,相关的说明之前的博客有写,我就不赘述了,还是不太会使用的同学请翻阅历史文档。

version: '3'

services:

nginx:

image: nginx:1.15.7-alpine

restart: always

labels:

- "traefik.enable=true"

- "traefik.port=80"

- "traefik.frontend.rule=Host:demo.soulteary.com,demo.soulteary.io"

- "traefik.frontend.entryPoints=https,http"

- "traefik.frontend.headers.customResponseHeaders=Access-Control-Allow-Origin:*"

networks:

- traefik

expose:

- 80

volumes:

- ./nginx.conf:/etc/nginx/nginx.conf

- ./mime.types:/etc/nginx/mime.types

- ./public:/app/public

- ./autoindex:/app/.autoindex

extra_hosts:

- "demo.soulteary.com:127.0.0.1"

- "demo.soulteary.io:127.0.0.1"

networks:

traefik:

external: true

当然,既然提到服务,最低要求是能够自动负载均衡、并且提供多节点存活,比如下面这样。

docker-compose up --scale nginx=2

最后

可能你会觉得这么一顿折腾,相比 Nginx 默认配置性能会有很大降低,然而事实是并没有,有兴趣的同学可以进行性能压测。

r语言默认工作目录document_使用 Docker 和 Nginx 实现简单目录索引服务相关推荐

  1. 使用docker部署nginx搭建简单的idea-2019 jrebel插件激活服务器

    使用docker部署nginx搭建简单的idea-2019 jrebel插件激活服务器 前言 之前用的jrebel激活方式一直都是用的 *lanyus* 大神的 [jrebel激活](http://i ...

  2. R语言-默认镜像设置

    问题1:如何设置默认镜像 你希望下载某些R包,因此希望设定默认的CRAN网站镜像,这样R每次下载时不需要你选择镜像. 解决方案 该方案要求用户R系统中包含一个.Rprofile文件,如方法3.16描述 ...

  3. ryuyan 方差分析_如何使用R语言做不同设计的方差分析(ANOVA)、简单效应检验、事后多重比较?...

    感谢 @hcp4715 和 @李晓煦 两位老师之前的精彩回答! 这个问题是我几个月前提的,当时还很少用R来做传统意义上的方差分析,所以比较想知道"如何使用R做方差分析.简单效应检验.事后多重 ...

  4. r语言 服务器网页版ide RStudio Server 简介

    目录 介绍 安装R 安装RStudio Server 创建账号 开始使用 注意事项 无法打开登录页 多用户使用 服务卡死 端口占用 外网使用 终端工具推荐 RStudio Server是网页版的RSt ...

  5. R语言学习笔记——入门篇:第一章-R语言介绍

    R语言 R语言学习笔记--入门篇:第一章-R语言介绍 文章目录 R语言 一.R语言简介 1.1.R语言的应用方向 1.2.R语言的特点 二.R软件的安装 2.1.Windows/Mac 2.2.Lin ...

  6. 「杂谈」如何写好R语言apply家族函数

    感觉好久没发有关R语言的博客了.这一年来,我着手开发了两个R包,但基本没怎么发博客. 原因也很简单,可能是我个人的私心吧,或者说是典型的"理论研究者"的"通病" ...

  7. R语言ggplot2可视化改变图中线条的透明度级别实战

    R语言ggplot2可视化改变图中线条的透明度级别实战 目录 R语言ggplot2可视化改变图中线条的透明度级别实战 #默认没有透明

  8. R语言ggplot2可视化将X轴置于ggplot2图表顶部实战

    R语言ggplot2可视化将X轴置于ggplot2图表顶部实战 目录 R语言ggplot2可视化将X轴置于ggplot2图表顶部实战 #ggplot2可视化默认X轴

  9. r语言清除变量_R语言(1)初识与数据结构

    点击上方蓝字,记得关注我们! a picture is worth a thousand words! 一,R语言简介 1,R语言的发展 上世纪90年代初,新西兰奥克兰大学 Ross Ihaka 和 ...

最新文章

  1. python dict排序 reduce函数
  2. 【计算理论】图灵机 ( 非确定性图灵机 | 非确定性图灵机指令分析 | 计算过程 | 非确定性指令出现多个分支 | 非确定性图灵机转为计算树 | 计算树 )
  3. tensorflow object detection API训练公开数据集Oxford-IIIT Pets Dataset
  4. 8.4 parted:磁盘分区工具
  5. 开始学习3年前的东西——MCMS
  6. 正则匹配中文 UTF-8 GBK
  7. 漫画 | 你真的会用烙铁焊接吗?
  8. bzoj 1016 [JSOI2008]最小生成树计数——matrix tree(相同权值的边为阶段缩点)(码力)...
  9. RMAN catalog 的创建和使用
  10. 阅读构建之法10、11、12章
  11. 和平精英有电脑版吗_和平精英华晨宇代言版-和平精英华晨宇代言版下载v1.9.10...
  12. AI 生态赋能 2018 论坛来袭!转型 AI 看这里!
  13. Smali动态调试方法
  14. 王坚数博会演讲实录:“计算经济”是社会发展的新动力
  15. 指向Member Function的指针
  16. 用c语言编写的迷宫游戏代码,C语言编写的迷宫小游戏 源代码
  17. DH算法图解+数学证明
  18. 关于下载安装pycharm专业版的步骤
  19. mysql导入错误1148,将CSV导入MySQL表会返回错误#1148
  20. lisp 圆柱螺旋线_Visual LISP开发三维圆柱螺旋线程序

热门文章

  1. 项目--------------使用BiLSTMCRF将病例文本中的诊断数据识别出来
  2. inodesusedpercent_Linux运维监控基础采集项
  3. 【Java报错】记录一次调用递归方法导致的 StackOverFlowError 及如何重构递归代码避免栈溢出
  4. 【MyBatis使用】mapper.xml 调试时无法打印SQL的无奈解决方法分享(原因说明+举例)
  5. SQL server判断字符串是否包含某个字符串
  6. XCTF WEB view_source
  7. Array Splitting
  8. Dima and a Bad XOR
  9. Chocolates
  10. 中文论文黑白矢量图绘制