- // 中间件的概念 控制是否向下执行 (权限处理)
- // 中间件 可以扩展 req 和 res中的方法
- // 中间件 一般放在路由之前
- // 中间件 可以提前处理一些逻辑 和 koa 用法一样
- // express 中间 如果路由 完全匹配 、 以中间件路径开头  或者路径是/ 都可以匹配到
- const express = require('./express');
- const app = express();
- // express 中的中间件可以放置路径 这个路径的规则 和 cookie中path的一样  {path:'/a'} /
- app.use(function (req,res,next) {
-     req.a = 1;
-     next();
- })
- app.use('/',function (req, res, next) {
-     req.a++;
-     next();
- })
- app.use('/a', function (req, res, next) {
-     req.a++;
-     next();
- })
- app.get('/a',function (req,res,next) {
-     res.end(req.a + '')
- })
- app.get('/', function (req, res, next) {
-     res.end(req.a + '')
- })
- app.listen(3000);
- const url = require('url');
- const Route = require('./route');
- const Layer = require('./layer');
- const methods = require('methods');
- function Router(){
-     this.stack = [];
- }
- Router.prototype.route = function (path) {
-     let route = new Route();
-     let layer = new Layer(path,route.dispatch.bind(route)); // 给当前调用get方法 放入一层
-     layer.route = route; // 每个层都有一个route属性 标识他是一个路由
-     this.stack.push(layer);
-     return route;
- }
- Router.prototype.use = function (path,handler) { // 中间件 会放到当前的路由系统中
-     if(typeof path === 'function'){
-         handler = path; // 给path默认值
-         path = '/'
-     }
-     let layer = new Layer(path,handler); // 产生一层 
-     layer.route = undefined; // 如果route是undefind 说明他是中间件
-     this.stack.push(layer);
- }
- methods.forEach(method=>{
-     Router.prototype[method] = function (path, handlers) { // 用户调用get方法时 传递了多个处理函数
-         let route = this.route(path); // 构建一个route的
-         route[method](handlers);  // 交给route 来存储用户的真正的handler
-     }
- })
- Router.prototype.handle = function (req,res,out) {
-     // 请求到来时 开始出路请求
-     let {pathname} = url.parse(req.url); // 获取请求来的路径
-     let idx = 0;
-     let dispatch =() => { // express 需要通过next函数来迭代
-         if (idx === this.stack.length) return out(); // 如果路由处理不了 交给application处理
-         let layer = this.stack[idx++];
-         // 路由 、 中间件 必须要求 路径匹配才ok
-         if (layer.match(pathname)) { // layer有可能是中间 还有可能是路由
-             if(!layer.route){ // 如果是中间件 直接执行 对应的方法即可
-                 layer.handle_request(req, res, dispatch);
-             }else{
-                 if (layer.route.methods[req.method.toLowerCase()]){
-                     layer.handle_request(req, res, dispatch);
-                 }else{
-                     dispatch();
-                 }
-             }
-         }else{
-             dispatch();
-         }
-     }
-     dispatch();
- }
- module.exports = Router;
- const http = require('http');
- const url = require('url');
- const path = require('path');
- const Router = require('./router');
- const methods = require('methods');
- function Application() { // 路由的配置 应该归属 应用来管理
- }
- Application.prototype.lazy_route = function () {
-     if(!this._router){
-         // 把应用和路由分离
-         this._router = new Router(); // 默认一调用express()
-     }
- }
- Application.prototype.use = function (path,handler) {
-     this.lazy_route();
-     this._router.use(path, handler)
- }
- // get post delete
- methods.forEach(method=>{
-     Application.prototype[method] = function (path, ...handlers) {
-         this.lazy_route();
-         this._router[method](path, handlers)
-     }
- })
- Application.prototype.listen = function () {
-     let server = http.createServer( (req, res) => {
-         // 获取请求的方法 
-         // 应用提供一个找不到的方法 如果路由内部无法匹配 调用此方法即可
-         function done(){
-             res.end(`Cannot ${req.method} ${req.url}`)
-         }
-         this.lazy_route();
-         this._router.handle(req,res,done)
-     });
-     server.listen(...arguments)
- }
- module.exports = Application;
- // 每次存储时一个对象
- function Layer(path,handler){
-     this.path = path;
-     this.handler = handler;
- }
- Layer.prototype.match = function (pathname) { // /a/b
-     if (this.path === pathname){
-         return true
-     }
-     // 如果是中间件 要特殊处理 
-     if(!this.route){
-         // 说明是中间件 
-         if(this.path === '/'){
-             return true;
-         }
-         return pathname.startsWith(this.path+'/')
-     }
- }
- Layer.prototype.handle_request = function (req,res,next) {
-     this.handler(req,res,next);
- }
- module.exports = Layer;
- // 每个层 都有一个route属性
- const Layer = require('./layer');
- const methods = require('methods');
- function Route(){
-     this.stack = [];
-     // 用于 匹配路径的时候 加速匹配,如果没有此方法的处理 直接跳过即可
-     this.methods = {}; // 他表示当前route中有哪些方法  {get:true,post:true}
- }
- Route.prototype.dispatch = function (req,res,out) {
-     let idx = 0;
-     let method = req.method.toLowerCase(); // 获取请求的方法
-     let dispatch = ()=>{
-         console.log('inner')
-         if (idx === this.stack.length) return out();
-         let layer = this.stack[idx++];
-         if (layer.method === method){ // 获取内部的第一层 看下是否方法匹配
-             layer.handle_request(req, res, dispatch)
-         }else{
-             dispatch();
-         }
-     }
-     dispatch();
- }
- methods.forEach(method => {
-     Route.prototype[method] = function (handlers) {
-         handlers.forEach(handler => {
-             let layer = new Layer('/', handler);
-             layer.method = method; // 用户调用什么方法 存入method就是什么
-             this.methods[method] = true; // 如果用户绑定方法 我就记录一下
-             this.stack.push(layer);
-         });
-     }
- });
- module.exports = Route;