Markdown在线预览上线了,拖动文件或者点击上传markdown文件就可以预览了。
服务器不保存文件副本,只是将上传的文件内容转换为html格式显示在网页上。
点击地址访问:3inns.cn/mdviewer
前端实现
支持拖拽和点击打开文件夹选择文件的方式
html代码
<div id="content">
<div id="dropbox">
<h1>Drop file here or click to upload</h1>
<h3>(The server does not keep a copy)</h3>
<h4 id="tips"></h4>
</div>
<div id="result"></div>
<input type="file" id="inputfile" name="file" style="display:none"/>
</div>
js代码
<script>
var dropbox = document.getElementById("dropbox");
dropbox.addEventListener("click", openfile, false);
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);
$('#inputfile').change(function() { upload($('#inputfile').get(0).files); })
function openfile(e) { $('#inputfile').click(); }
function dragenter(e) { e.stopPropagation(); e.preventDefault(); }
function dragover(e) { e.stopPropagation(); e.preventDefault(); }
function drop(e) { e.stopPropagation(); e.preventDefault(); upload(e.dataTransfer.files); }
var tips = $('#tips');
function upload(files) {
if (files === undefined) {
return;
}
if (files.length !== 1) {
tips.text('Tips:Only one file can be uploaded.');
return;
}
var fileObj = files[0];
if (fileObj.size > 5 * 1024 * 1024) {
tips.text('Tips:No more than 5M.');
return;
}
var FileController = "../mdfile"; // 接收上传文件的后台地址
var form = new FormData();
form.append("author", "3inns.cn");
form.append("file", fileObj); // 文件对象
var xhr = new XMLHttpRequest();
xhr.open("post", FileController, true);
xhr.onload = function (e) {
console.log('over');
};
xhr.onreadystatechange = function() {
$('#dropbox').hide();
$('#result').html(xhr.responseText);
}
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = Math.round(evt.loaded * 100 / evt.total);
console.log(percentComplete);
tips.text('Tips:' + percentComplete + '%');
} else {
tips.text('Upload failed!');
}
}, false);
xhr.send(form);
}
</script>
后台实现
使用的是koa2
引入koaBody模块
const koaBody = require('koa-body');
...
app.use(koaBody({ multipart: true }))
路由以及实现
使用marked模块转换markdown文本为html格式
app.use(route.get('/mdviewer', Extends.mdviewer))
app.use(route.post('/mdfile', Extends.mdfile))
// Extends对象
module.exports.mdviewer = async function(ctx) {
ctx.body = await ctx.render('md_viewer');
}
const readFilePromise = (path) => {
return new Promise((resolve, reject) => {
fs.readFile(path, 'utf8', (err, data) => {
if (err) {
return reject();
}
return resolve(data);
})
})
}
module.exports.mdfile = async function(ctx, next) {
if ('POST' != ctx.method) {
return await next();
}
if (ctx.request.body.files && ctx.request.body.files.file) {
const author = ctx.request.body.fields.author;
const file = ctx.request.body.files.file;
const content = await readFilePromise(file.path);
if (content && content.length) {
const html = marked(content);
ctx.body = html;
} else {
return await next();
}
} else {
return await next();
}
}
代码不多实现起来也不复杂,暂时没考虑各浏览器的兼容性问题,相信大家用的都是新版浏览器。