共计 2131 个字符,预计需要花费 6 分钟才能阅读完成。
express 框架实现
const http = require("http"); | |
const url = require("url"); | |
function createApp() {var app = {}; | |
var routes = []; | |
// 将所有请求方式写入 app 对象中 | |
http.METHODS.forEach(method => {method = method.toLocaleLowerCase(); | |
app[method] = (path, handler) => { | |
let route = { | |
path, | |
method, | |
handler | |
}; | |
routes.push(route); | |
}; | |
}); | |
// 匹配剩余路由 | |
app.all = (path, handler) => { | |
let route = { | |
method: "all", | |
path, | |
handler | |
}; | |
routes.push(route); | |
}; | |
// 中间件 | |
app.use = (path, handler) => {if(handler === undefined) { | |
handler = path; | |
path = "/"; | |
} | |
let route = { | |
method: "middle", | |
path, | |
handler, | |
} | |
routes.push(route); | |
} | |
// 服务 | |
let server = http.createServer((req, res) => {let method = req.method.toLocaleLowerCase(); | |
let {pathname} = url.parse(req.url, true); | |
pathname = decodeURI(pathname); | |
// 循环路由,匹配到就执行它的 handler 函数 | |
// 用 next 函数 | |
let i = 0; | |
let next = () => {if(i >= routes.length) return; | |
let {method: m, path: p, handler: h} = routes[i]; | |
i++; | |
if(m === 'middle') { | |
// 匹配中间件 | |
if(p == '/' || p == pathname || pathname.startsWith(p+'/')) {h(req, res, next); | |
} else {next(); | |
} | |
} else { | |
// 匹配一般路由 | |
if ((m == method || m == "all") && (p == pathname || p === "*")) {h(req, res); | |
} else {next(); | |
} | |
} | |
} | |
next();}); | |
app.listen = (...rest) => {server.listen(...rest); | |
}; | |
return app; | |
} | |
module.exports = createApp; |
静态资源服务中间价实现
const path = require("path"); | |
const fs = require("fs"); | |
const url = require('url'); | |
const mime = { | |
css: "text/css", | |
gif: "image/gif", | |
html: "text/html", | |
ico: "image/x-icon", | |
jpeg: "image/jpeg", | |
jpg: "image/jpeg", | |
js: "text/javascript", | |
json: "application/json", | |
pdf: "application/pdf", | |
png: "image/png", | |
svg: "image/svg+xml", | |
swf: "application/x-shockwave-flash", | |
tiff: "image/tiff", | |
txt: "text/plain", | |
wav: "audio/x-wav", | |
wma: "audio/x-ms-wma", | |
wmv: "video/x-ms-wmv", | |
xml: "text/xml", | |
unknown: "text/plain" | |
}; | |
function static(basename) {return (req, res, next) => {let { pathname} = url.parse(req.url, true); | |
pathname = decodeURI(pathname); | |
let p = path.resolve(path.join(basename, pathname)); | |
fs.stat(p, (err, stats) => {if(err) next(); | |
if(stats && stats.isFile()) {let ext = path.extname(p).slice(1); | |
res.writeHead(200, {"content-type": `${mime[ext]};charset=utf-8`}) | |
let rs = fs.createReadStream(p); | |
rs.pipe(res); | |
} else {next(); | |
} | |
}) | |
} | |
} | |
module.exports = static; |
使用
const createApp = require('./app/index'); | |
const static = require('./app/static'); | |
let app = createApp(); | |
app.use(static('./static')); | |
app.all('*', (req, res) => {res.end('404'); | |
}); | |
app.listen(8080, '127.0.0.1'); |
正文完
发表至: javascript
2019-08-22