node中的express

1,041 阅读3分钟

express

npm init 
npm install ejs body-parser express

http.server

let http = require('http');
const url = require('url');
http.createServer(function (req, res) {
  let { query, pathname } = url.parse(req.url, true);
  if (pathname == '/signin') {
    let str = '';
    req.on('data', function (chunk) {
      str += chunk;
    })
    req.on('end', function () {
      console.log(str);
    })
    res.setHeader('Content-Type', 'text/plain;charset=utf8');
    return res.end('登录')
  }
  if (pathname == '/signup') {
    res.setHeader('Content-Type', 'text/plain;charset=utf8');
    return res.end('注册')
  }

}).listen(8080);
const express = require('express');
// 引用express模块, express是个函数\
const app = express(); // express函数执行后返回的是一个http的监听函数,就是http.createServer中的函数


// 测函数上扩展了个listen可以监听端口
app.listen = function(...args){
  require('http').createServer(app).listen(...args);
}
// app.listen是基于以前封装的
// app.listen(8080, function(){
//   console.log(`start8080`)
// })

express route

const express = require('express');
const app = express();
app.listen(3000, ()=>{
  console.log('运行于3000')
});
// app 监听函数上扩展了很多方法,包括get、post、delete、put、RESful风格中的动词
// app.方法名('路径名', fn)
// 从上向下匹配如果匹配到了结束相应
// 路径知道 pathname,没有问好后面的内容
// express重点扩展req和res的属性
app.get('/signin',function(req, res){
  res.setHeader('Content-Type', 'text/plain;charset=utf8');
  res.end('登录')
});
app.post('/signup',function(req, res){
  res.end('注册')
});
app.all('*', function(req, res){
  res.end('404');
})

req.attribute

const express = require('express');
const app = express();
app.listen(8080);
//相区分查询一个还是所有
app.get('/user', function (req, res) {
  console.log(req.query.id);
  console.log(req.url);
  console.log(req.path);
  console.log(req.headers);// 所有都小写
  console.log(req.method);// 都是大写
})

route params

const express = require('express');
const app = express();
app.listen(8080);

// /user?id=1 查一个,/user查所有 路径都是/user
// /user/1 表示查一个 /user查所有
app.get('/user', function (req, res) {
  res.end('select all')
});

// id是占位符,必须有但随即
// /user/1/2=>{id:1, name:2} = params;一一对应
app.get('/user/:id/:name', function (req, res) {
  res.end('select one'+req.params.id+req.params.name);
});

let url = '/user/1/2/a';
let url2 = '/user/:id/:name/a'; // {id:1, name:2}

// 将url2转化成可以匹配url的正则
let arr = [];
let newReg = url2.replace(/:[^\/]+/g, function(){
  arr.push(arguments[0].slice(1));
  return '([^\/]+)'
});
let reg = new RegExp(newReg);
let newArr = reg.exec(url);
let result = {};
arr.forEach(function(item, index){
  result[item] = newArr[index+1]
});
console.log(result);
const express = require('express');
const app = express();
app.listen(8080);

// 拦截功能,req和res都是同一个
app.param('id', function(req, res, next){
    let req.params.id = `你的学号是${req.params.id}`;
    next();
});
app.param('name', function(req, res, next){
    let req.params.name = `你的姓名是${req.params.name}`;
    next();
});
app.get('/user/:id/:name', function (req, res) {
    res.header('Content-typy','text/plain;charset=utf-8')
    res.end(`${req.params.id}${req.params.name}`);
});

7.中间件middleWare

当我们访问最终目标之前执行的内容

const express = require('express');
const app = express();
app.listen(8080);

//1. 中间件的第一个功能 可以进行权限判断
//2. 可以进行对req和res的扩充
//3. 中间件放在执行路径的上面
//4. 中间件默认情况下都匹配,可以指定匹配什么开头的
app.use('/water', function(req, res, next){// 不调用next不继续往下走
    console.log('过滤石头');
    req.stone = 'too big';
    next('错误');// 这里也会走,不过end只显示过滤石头
});
app.use('/water',function(req, res, next){// 不调用next不继续往下走
    console.log('过滤沙子');
    req.send = 'too small';
    next();
});
// 统一处理
app.use(function(req, res, next){
    res.header('Content-type','text/plain;charset=utf-8');
    next();
})
app.get('/water/a', function(req, res){// 前面匹配到就生效
    console.log(req.stone, req.send)
    res.end('water');
})
app.get('/food', function(req, res){
    console.log(req.stone, req.send)
    res.end('food');
})
app.use(function(err, req, res, next){// 错误中间件有四个参数 fn.length === 4
    console.log(err);
})

例子

const express = require('express');
const app = express();
app.listen(8080);

app.use(function(req, res, next){
    let t = new Date().getTime();// 访问最初的时间,还要记录end时间
    let end = res.end;
    res.end = function(...arg){
        end.call(res,...arg);
    }
    next();
});
app.get('water', function(req, res){
    for(let i=0;i<1000, i++){
    }
    res.end('water');// 装饰模式
});
app.get('food', function(req, res){
     for(let i=0;i<10000, i++){
    }
    res.end('food');
})

decorator

function coffee(){
    console.log('来一个咖啡');
}
function sweetCoffee(){
    coffee();
    console.log('加糖')
}
coffee();
sweetCoffee();
next原理
middleWare实现

function app(){
    
}
// 每次调用use方法,都会将方法存到数组中,默认调用数组的第一项,将next方法传递给数组中函数,如果调用此函数,会继续执行数组中的下一项
app.middleware = [];
app.use = function (cb) {
    this.middleware.push(cb);
}
app.use(function(req, res, next){
    console.log(1);
    next();
});
app.use(function(req, res, next){
    console.log(2);
    next();
});
app.use(function(req, res, next){
    console.log(3);
    next();
});
let index = 0;
function next() {
    app.middleware[index++](null, null, next);
};
next();

res新加的方法和属性

const express = require('express');
const app = express();
app.listen(8080);

// 不能直接返回对象 res.json();
// 返回thml页面 res.sendFile();返回文件
// res.statusCode res.end = res.sendStatus();
// res.end() res.header(); = res.send(); 

app.get('/json', function(req, res){
    res.json({name:xxx,age: 9});
})
app.get('/', function(req, res){// root不能通过../访问上一级目录
    // res.sendFile(__dirname + '/index.html'');
    res.sendFile('./index.html',{root: __dirname});// 一般用这个
    res.sendFile(require('path').join(__dirname, '..', 'index.html'));// 查找上一级
});
app.get('/status', function(req, res){
    res.sendStatus(404);
});
app.use(function(req, res, next){
    res.mySend = function(data){
        if(typeof data === 'object'){
            res.setHeader('Content-Type','application/json;chartset=utf8');
            return res.send(JSON.stringify(data));
        }
        if(typeof data === 'string'){
            res.setHeader('Content-Type','text/plain;chartset=utf8');
            return res.send(data);
        }
        if(typeof data === 'number'){
            res.statusCode = data;
            res.end(require('_http_server').STATUS_CODES[data]);
        }
    }
    next();
})
app.get('/send', function(req, res){
    // res.send({name: 'xxx', age: 9});
    // res.end(200);
    res.mySend();
})