第一步,用node输出一个hello world
var http=require('http')http.createServer(function(req,res){
var urlPares=url.parse(req.url)
var query=querystring.parse(urlPares.query)
res.end('hello world')
}).listen(80)
大部分的node教程在这里会告诉你,我们很容易的建立的一个服务器。但是在实际使我们通常使用的是express.(f**k,难道Node必须要用express吗?自己实现一个Web应用框架真的很难吗?)其实并不是。
那么既然打算自己写我们首先要知道我们要做哪些事情。 1.路由或者智能路由 2.静态文件输出 3.session/cookie 4.模版渲染 5.数据库处理 6.文件上传
第二步,路由
路由好高大上的名字,它是干啥的?url对应具体方法就是它该做的事情。 那么我们为什么不让url对应xxx文件的xx方法。 例如:/user/login能不能自动对应到user.js的login方法上。实现起来很难么?其实只需要几句代码
var fs = require("fs")
module.exports=function(req,res){
var query=req.query
var urlPares=req.urlPares
var pathname=urlPares.pathname
var arr=pathname.split("/")
req.arr=arr
//start 这段代码处理默认行为。可以先忽略
if(arr.length==0||arr.length==1){
arr=["","index","index"]
}else if(arr.length==2){
arr.push("index")
}
if(arr[1]==""){
arr[1]="index"
}
if(arr[2]==""){
arr[2]="index"
}
//end 这段代码处理默认行为。可以先忽略
if (fs.existsSync(APP_PATH+'/controller/'+arr[1]+'.js')){
var controller=require('./controller/'+arr[1])
if(controller[arr[2]]){
controller[arr[2]](req,res)
}else{
res.writeHead(404,{'Content-Type': 'text/plain' })
res.end("你访问的控制器不存在指定方法")
}
}else{
res.writeHead(404,{'Content-Type': 'text/plain' })
res.end("你访问的路径不存在")
}
}
通过fs判断文件是否存在。然后去require它就行了。APP_PATH是个全局变量表示程序入口的路径。
第三步,静态文件输出
静态文件输出我们需要一个库MIME
var url = require("url")
var fs = require("fs")
var mime = require('mime')
/**
* [[检测是否为静态资源]]
* @param {Object} req [[Description]]
* @param {[[Type]]} res [[Description]]
* @returns {bool} [[Description]]
*/
module.exports = function (req, res) {
//正则表达式检测文件后缀
var url_resource_reg = /.*\.(html|htm|gif|jpg|jpeg|bmp|webp|htc|swf|png|ico|txt|js|css)/
if (!url_resource_reg.test(req.url)) {
return false
}
var urlPares = url.parse(req.url)
var pathname = urlPares.pathname
var fileUrl = APP_PATH + "/static" + pathname
if (fs.existsSync(fileUrl)) {
var contentType = mime.lookup(fileUrl)
res.setHeader('Content-Type', contentType || "text/plain")
var fileStream = fs.createReadStream(fileUrl)
fileStream.pipe(res)
fileStream.on('end', function () {
res.end()
})
return true
} else {
return false
}
}
第四步,session/cookie
这里稍微有点。但是代码量也不多
var sessions = {}
var sessionKey = 'session_key'
var EXPIRES = 30 * 60 * 1000
function randString(size) {
var result = ''
var allChar = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
size = size || 1
while (size--) {
result += allChar.charAt(rand(0, allChar.length - 1))
}
return result
}
var generate = function () {
var session = {}
session.id = Date.now() + randString(12)
session.cookies = {
expire: Date.now() + EXPIRES
}
sessions[session.id] = session
return session
}
var parseCookie= function (cookie) {
var cookies = {}
if (!cookie) {
return cookies
}
var list = cookie.split("")
for (var i = 0 i < list.length i++) {
var pair = list[i].split("=")
cookies[pair[0].trim()] = pair[1]
}
return cookies
}
var serializeCookies = function (cookies) {
var arr = []
for (var key in cookies) {
arr.push(serialize(key, cookies[key]))
}
return arr
}
var serialize = function (name, value, option) {
var pairs = [name + '=' + encodeURI(value)]
//设置cookie默认共用"/"路径
option = option || {
path: "/"
}
if (option.maxAge) pairs.push('Max-Age=' + option.maxAge)
if (option.domain) pairs.push('Domain=' + option.domain)
if (option.path) pairs.push('Path=' + option.path)
if (option.expires) pairs.push('Expires=' + option.expires)
if (option.httpOnly) pairs.push('HttpOnly')
if (option.secure) pairs.push('Secure')
return pairs.join(' ')
}
module.exports = function (req, res) {
req.cookies = parseCookie(req.headers.cookie)
var id = req.cookies[sessionKey]
if (!id) {
req.session = generate()
} else {
var session = sessions[id]
if (session) {
if (session.cookies.expire > Date.now()) {
session.cookies.expire = Date.now() + EXPIRES
req.session = session
} else {
delete sessions[id]
req.session = generate()
}
} else {
req.session = generate()
}
}
for (var key in sessions) {
if (sessions[key].cookies.expire < Date.now()) {
delete sessions[key]
}
}
var writeHead = res.writeHead
res.writeHead = function () {
delete req.cookies[ham_sessionKey]
var sessionStr = serialize(ham_sessionKey, req.session.id)
res.setHeader('Set-Cookie', serializeCookies(req.cookies).concat(sessionStr))
return writeHead.apply(res, arguments)
}
}
第五步,模版渲染
这是最简单的。
第六步,数据库处理
这里可以是用一些ORM框架。
第七步,文件上传,post
第八步,就是你把上面的代码组织起来。
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)