摘要:问题暴露之前做的浏览是使用版本做的,因为参考书比较旧了。方法可以将本地文件以静态资源发送给用户,所有问题迎刃而解。旧版本不支持等代码文件和文件在线查看,所以进行改进。利用和进行响应式布局。监控文件,改变后无需重启服务器。
问题暴露
之前做的HTTP浏览是使用express2.x版本做的...,因为参考书比较旧了。
express2.x中没有express4.x中的res.sendFile()方法,之前发送文件是使用的stream.pipe()方法,导致不支持继续下载,而且用户不能知道下载进度,在线音乐视频播放也不能选择时间跳跃欣赏。res.sendFile()方法可以将本地文件以静态资源发送给用户,所有问题迎刃而解。
旧版本不支持java/c/cpp/js/css/html等代码文件和md/markdown文件在线查看,所以进行改进。
利用Bootstrap responsive utils和Bootstrap grid system进行响应式布局。
监控root.txt文件,改变root后无需重启服务器。
去除对q.js依赖,使用原生Promise
效果预览
json文件查看
md文件查看
html文件查看
代码改进 root.txt文件监控//全局对象 global.root = fs.readFileSync("./root.txt").toString().split(/s+/)[0]; fs.watchFile("./root.txt",function () { //root.txt 文件修改后触发 global.root = fs.readFileSync("./root.txt").toString().split(/s+/)[0]; });原生Promise
var statP = function(root,file){ return new Promise(function(resolve){ fs.stat(root+"/"+file,function (err, stats) { var t = {}; if(err){ t.reason=err; resolve(t); } else { t.state="ok"; stats.name = file; stats.type = stats.isDirectory()?"文件夹":"文件"; t.value=stats; resolve(t); } }); }) }; Promise.all(files.map((x,i,a)=>{return statP(r,x);})) .then(function (results) { var values = []; results.forEach(x=>{ if(x.state==="ok"){ values.push(x.value); }else console.error(x.reason); }); //...render },console.error);sendFile方法使用
// noraw为url上的noraw参数值 if(!!noraw){ // f为文件名 if(f.match(/.(avi|mp4|mkv|rmvb|mpg|rm|wma)$/i)){ res.render("video",o); }else if(f.match(/.(jpg|png|bmp|jpeg|gif)$/i)){ res.render("img",o); }else if(f.match(/.(mp3|wma|aac)$/i)){ res.render("audio",o); }else if(f.match(/.(md|markdown)$/i)){ fs.readFile(file,(error,data) => { if(error) throw error; o.content = data.toString(); res.render("md",o); }); }else if(f.match(/.(java|c|cpp|js|css|jsp|php|json|txt)$/i)){ fs.readFile(file,(error,data) => { if(error) throw error; // 在服务器渲染高亮代码方法被淘汰,因为对大文件调用下面方法十分耗时间, // 而node为单线程,所以其他用户请求也会被阻塞,而且本用户也要等待很久。 // 所以选择在浏览器端解析。 // console.time("hl"); // o.content=hl.highlightAuto(data.toString()).value; // console.timeEnd("hl"); o.content = data.toString(); res.render("code",o); }); }else if(f.match(/.(html|htm)$/i)){ fs.readFile(file,(error,data) => { if(error) throw error; o.content = data.toString(); res.render("html",o); }); }else{ // rela 为相对路径,root 为文件根目录 res.sendFile(rela,{root:global.root}); } }else{ res.sendFile(rela,{root:global.root}); }layout.jade
doctype html(lang="zh") head title= title meta(name="renderer",content="webkit") meta(http-equiv="X-UA-Compatible",content="IE=edge") meta(name="viewport" content="width=device-width, initial-scale=1") link(rel="stylesheet", href="/stylesheets/bootstrap.min.css") link(rel="stylesheet", href="/stylesheets/style.css") link(rel="stylesheet", href="/stylesheets/hljs-github.min.css") link(rel="stylesheet", href="/stylesheets/pilcrow.css") link(rel="stylesheet", href="/stylesheets/github-markdown.css") body block contentcode.jade
extends layout block content script(src="http://cdn.bootcss.com/highlight.js/8.0/highlight.min.js") div.container-fluid h1=title include btns div.markdown-body pre code!=content script hljs.initHighlightingOnLoad();//自动寻找md.jade进行解析 footer p.text-center.text-info Running on node with Express, Jade. By Moyu.
// Created by Yc on 2016/6/9. extends layout block content script(src="http://cdn.bootcss.com/marked/0.3.5/marked.min.js") script(src="http://cdn.bootcss.com/highlight.js/8.0/highlight.min.js") div.container-fluid h1=title include btns div.row div.col-lg-6.visible-lg h2 解析前 div.markdown-body pre code(id="markdown-raw")=content //"="会被转义(如 < : <),"!="不会 div.col-lg-6 h2 解析后 div.markdown-body(id="markdown-show") script(src="/javascripts/md.js") //renderer 来自md.js script document.getElementById("markdown-show").innerHTML = marked(document.getElementById("markdown-raw").innerText,{renderer:renderer}); footer p.text-center.text-info Running on node with Express, Jade. By Moyu.md.js
~function(){ marked.setOptions({ highlight: function (code) { return hljs.highlightAuto(code).value; } }); renderer = new marked.Renderer(); var map = {}; //重写默认"#","##"... 格式的转换方法 renderer.heading = function (text, level) {//level 表示层级,如#为1,##为2 var escapedText = text.toLowerCase(); // 防止出现重复的锚点 if(!!map[text]) escapedText+="-"+map[text]++; else map[text]=1; return "问题归纳" + text + " "; }; }();
通过url的noraw控制展示方式,对SEO不友好
GitHub的解决方法是,在raw文件提供独立的三级域名raw.githubusercontent.com/{username}/{repo}/{branch}/{file}
后期希望更加完善这个web应用吧,比如在线查看压缩文件等功能。
代码地址http-file-explorer-express4.x
参考资料markdown-styles: 提供高大上的CSS样式。
marked: 提供强大的markdown格式转化API。
highlight.js: 提供强大的code格式转化为具有class样式的标签,方便用户自定义样式。
express4.x: express4.x详细API文档。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/86338.html
摘要:前言缓存探究第一弹中我们讲了一些缓存的基础知识和策略。第二弹我们来讲讲如何实际在项目中配置。在缓存探究第一弹定制缓存策略中已经提到对于最好标记为不缓存,以便及时获取最新的静态资源版本。 前言 WEB缓存探究第一弹中我们讲了一些WEB缓存的基础知识和策略。第二弹我们来讲讲如何实际在项目中配置。 实战 鉴于叉烧包本包是个前端,所以我们就以HTML和Node为例开始showImg(https...
摘要:前言缓存探究第一弹中我们讲了一些缓存的基础知识和策略。第二弹我们来讲讲如何实际在项目中配置。在缓存探究第一弹定制缓存策略中已经提到对于最好标记为不缓存,以便及时获取最新的静态资源版本。 前言 WEB缓存探究第一弹中我们讲了一些WEB缓存的基础知识和策略。第二弹我们来讲讲如何实际在项目中配置。 实战 鉴于叉烧包本包是个前端,所以我们就以HTML和Node为例开始showImg(https...
摘要:前言缓存探究第一弹中我们讲了一些缓存的基础知识和策略。第二弹我们来讲讲如何实际在项目中配置。在缓存探究第一弹定制缓存策略中已经提到对于最好标记为不缓存,以便及时获取最新的静态资源版本。 前言 WEB缓存探究第一弹中我们讲了一些WEB缓存的基础知识和策略。第二弹我们来讲讲如何实际在项目中配置。 实战 鉴于叉烧包本包是个前端,所以我们就以HTML和Node为例开始showImg(https...
摘要:前言缓存探究第一弹中我们讲了一些缓存的基础知识和策略。第二弹我们来讲讲如何实际在项目中配置。在缓存探究第一弹定制缓存策略中已经提到对于最好标记为不缓存,以便及时获取最新的静态资源版本。 前言 WEB缓存探究第一弹中我们讲了一些WEB缓存的基础知识和策略。第二弹我们来讲讲如何实际在项目中配置。 实战 鉴于叉烧包本包是个前端,所以我们就以HTML和Node为例开始showImg(https...
摘要:前言学习也有一段时间了,踩过许多坑,在这里打算记录一下自己觉得有用的点,以备以后所需。代码调试一般我们调试项目都是通过前端或者后端,这总是显得不够灵活。即使是内置的也不够友好。这样修改文件时服务就会自动重启了。 前言 学习NodeJs也有一段时间了,踩过许多坑,在这里打算记录一下自己觉得有用的点,以备以后所需。 代码调试 一般我们调试Js项目都是通过Alert()(前端)或者 Cons...
阅读 1830·2021-11-22 15:24
阅读 1291·2021-11-12 10:36
阅读 3125·2021-09-28 09:36
阅读 1793·2021-09-02 15:15
阅读 2648·2019-08-30 15:54
阅读 2375·2019-08-30 11:02
阅读 2364·2019-08-29 13:52
阅读 3506·2019-08-26 11:53