node.js封装一个类似express框架
express基础使用方法:
详情可参考官网https://www.npmjs.com/package/express
const express = require('express')
const app = express()
app.get('/', function (req, res) {
res.send('Hello World')
})
app.listen(3000)
node.js封装一个类似express框架
实现的基本思路---思路案例一:
/**
* 最终目标是以这样的方式配置路由
* app.get('/',function(req,res){
* res.send('hello world')
* })
*/
思路转变:
//函数也是对象,那么就能不断的往app上添加属性
let app=function(){
console.log('app方法')
}
app.get=function(){
console.log('get方法')
}
app.post=function(){
console.log('post方法')
}
//调用
app.get() //'get方法'
app.post() //'post方法'
app() //'app方法'
思路转变:
//定义一个空对象
let G={};
//函数也是对象,那么就能不断的往app上添加属性
let app=function(req,res){
//如果存在G['/']则去执行该属性对应的方法
if(G['/']){
G['/'](req,res) //执行方法
}
}
app.get=function(str,cb){
//注册方法
G[str]=cb;
/**
* 等价于---给对象G上添加属性和属性值
* 注册方法
* G['/']=function(req,res){
console.log('执行login方法')
}
*/
}
//调用---通过这种方法配置路由
//---注册并执行方法
app.get('/',function(req,res){
console.log('执行login方法')
}) //执行login方法
该构建的目录结构为:
下面是module/router.js的页面代码
这是作为第三方模块被入口文件express.js引入
const url=require('url')
const path=require('path')
const fs=require('fs')
//扩展res.send方法
function changeRes(res){
res.send=(data)=>{
res.writeHead(200, {'Content-Type': 'text/html;charset="utf-8"'});
res.end(data);
}
/*
function send(data){
res.writeHead(200, {'Content-Type': 'text/html;charset="utf-8"'});
res.end(data);
}
*/
}
//根据文件后缀名获取content-type的所需值
//封装为一个私有方法--不需要暴露
let getFileMine=function(extname){
var data=fs.readFileSync('./data/mime.json') //同步方法拿到数据
let mimeObj=JSON.parse(data.toString());
return mimeObj[extname]
}
//构建静态web服务器的方法
let initStatic=function(request,response,staticPath){
//1.获得pathname--例如/index.html
let pathname=url.parse(request.url).pathname;
pathname=pathname=='/'?'/index.html':pathname
//2.可以获取后缀名
let extname=path.extname(pathname)
//3.通过fs模块读取文件
try {
//根据pathname(通过输入的url获取)判断指定的文件(例如./static/login.html)存不存在
var data=fs.readFileSync('./'+staticPath+pathname)
//存在的话
if(data){
let mime=getFileMine(extname)
response.writeHead(200, {'Content-Type': 'text/html;charset="utf-8"'});
response.end(data); //不加载css样式
}
} catch (error) {
console.log('error', 'error')
}
}
//为了更安全再把它放在server函数里
let server=()=>{
let G={
_get:{},
_post:{},
//默认的静态web目录
staticPath:'static'
};
//函数也是对象
let app=function(req,res){
//扩展res的方法
changeRes(res);
//配置静态web服务
initStatic(req,res,G.staticPath)
//http://127.0.0.1:3000/news --->/news
let pathname=url.parse(req.url).pathname
//获取请求类型
let method=req.method.toLowerCase();
//
if(G['_'+method][pathname]){
if(method=='get'){
// G['_'+method][pathname](req,res)
G._get[pathname](req,res) //执行方法
}else{
//获取post的数据把它绑定到req.body里面
let postData='';
req.on('data',(chunk)=>{
postData+=chunk;
})
req.on('end',()=>{
console.log(postData)
// res.end(postData)
req.body=postData
//请求完成之后执行方法
G._post[pathname](req,res)
})
}
}else{
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end('opps');
}
}
app.get=function(str,cb){
//注册方法
G._get[str]=cb;
/**
* 执行了app.get方法等价于在注册了G._get对象上注册了方法
* G._get['/']=function(req,res){
res.send('hello world')
}
*/
/**
*
* G['/login']=function(req,res){
* res.writeHead(200, {'Content-Type': 'text/plain'});
* res.end('Hello World www');
* };
*
*/
}
}
//配置post请求
app.post=function(str,cb){
G._post[str]=cb;
// G['/login']=function(req,res){
// res.writeHead(200, {'Content-Type': 'text/plain'});
// res.end('Hello World www');
// };
}
// 静态web服务目录
app.static=function(staticPath){
G.staticPath=staticPath;
}
//等价于暴露app
return app;
//等价于暴露app
module.exports=server();
下面是express.js的页面代码
var http = require('http');
var app=require('./module/router');
const ejs=require('ejs');
/*
http.createServer(function (request, response) {
}).listen(3000);
*/
//一请求就触发app方法---注册web服务
http.createServer(app).listen(3020);
//配置web静态目录
app.static('static')
//配置路由---注册
app.get('/login',function(req,res){
// res.writeHead(200, {'Content-Type': 'text/plain'});
// res.end('Hello World');
ejs.renderFile('./view/form.ejs',{},(err,data)=>{
res.writeHead(200, {'Content-Type': 'text/html;charset="utf-8"'});
res.end(data);
})
})
app.get('/',function(req,res){
res.send('hello sssss')
// res.writeHead(200, {'Content-Type': 'text/html;charset="utf-8"'});
// res.end('Hello World www');
})
app.post('/doLogin',function(req,res){
console.log(req.body)
res.send(req.body)
// res.writeHead(200, {'Content-Type': 'text/plain'});
// res.end(req.body);
})
前后端交互一
- 利用nodejs模拟服务器端
- 实现的依赖有:
const Koa = require("koa");
//静态资源托管
const static = require("koa-static");
//动态路由搭建
const Router = require("koa-router");
//通过ctx.request.body来获取post请求提交过来的数据
const koaBody = require("koa-body");
const fs = require("fs");
//文本JSON格式数据-自动转为对象
const usersData = require("./data/users.json");
/* userData的对象数据
[{
"id":1,
"username":"张三",
"pwd":123
},{
"id":1,
"username":"李四",
"pwd":123
}]
*/
let app = new Koa();
//托管静态资源--托管static目录下的静态资源
app.use(static(__dirname+"/static"));
//每一个请求都用到了此中间件(有点性能浪费)
app.use(koaBody({
multipart:true //允许接收文件
}));
//实例化Router
let router = new Router();
//测试动态路由
router.get("/",(ctx,next)=>{
ctx.body = "hello";
})
//启动
app.use(router.routes());
app.listen(8888);