Node学习(二)

一、流

1.1可读流

//创建可读流 __dirname当前文件
let readable = fs.createReadStream(path.join(__dirname,'xxxxx'));

1.2可写流

//可写流
let writable = fs.createWriteStream(path.join(__dirname,'xxxxx'))
//读流 chunk每一次接收到的数据
readable.on('data',chunk => {
    writable.write(chunk);
});
readable.on('error',err => {
    console.log('====>',err);
    console.log('====>','读取失败');
});

readable.on('end',() => {
    console.log('====>',"读完了");            
});

1.3管道流

当在可读流上调用 stream.pipe() 方法时会发出 ‘pipe’ 事件,并将此可写流添加到其目标集。

 	//创建可读流
    let readable = fs.createReadStream(path.join(__dirname,'jquery-3.5.1.js'));
    //可写流
    let writable = fs.createWriteStream(path.join(__dirname,'jquery1-3.5.1.js.gz'))
    //创建压缩
    let gz = zlib.createGzip();
    //管道流
    readable.pipe(gz).pipe(writable);

二、完善一个静态服务器

三、NPM

Node学习(二)_第1张图片

3.1node包管理工具

全局安装:npm install xxxx -g
本地安装位置:npm root -g

本地安装:
–save 生产依赖 vue jQuery
–save-dev 开发依赖 webpack、 less
例:npm i less --save-dev

3.2nodemon热部署

安装:npm i -g nodemon
使用:nodemon xxx.js

四、yarn

Node学习(二)_第2张图片
①cnpm i xxx
②npm install -g cnpm --registry=https://registry.npm.taobao.org
上面俩个功能xiangt

设置配置: npm config set registry https://registry.npm.taobao.org
查看配置: npm config get registry
查看全部配置: npm config list

五、模板引擎

首先安装:npm i art-template koa-art-template -S
模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。

5.1art-template

art-template是一个简约的、超快的模板引擎
它采用作用域预声明的技术来优化模板渲染速度,从而获得接近JavaScript极限的运行性能,并且同时支持NodeJS和浏览器

5.1.1特性

(一)拥有接近JavaScript渲染极限的性能
(二)调试友好:语法、运行时错误日志精确到模板所在行;支持在模板文件上打断点
(三)支持Express、Koa、Webpack
(四)支持模板继承与子模板
(五)浏览器版本仅6KB大小

5.1.2模板

art-template 同时支持两种模板语法。标准语法可以让模板更容易读写;原始语法具有强大的逻辑处理能力。

标准语法:

{
     {
     if user}}
  <h2>{
     {
     user.name}}</h2>
{
     {
     /if}}

原始语法:

<% if (user) {
      %>
  <h2><%= user.name %></h2>
<% } %>

5.1.3渲染模板

var template = require('art-template');
var html = template(__dirname + '/tpl-user.art', {
     
    user: {
     
        name: 'aui'
    }
});

5.1.4核心方法

(一)基于模板名渲染模板template(filename, data);

let art = `
        <ul>
            {
     {
     each arr}}
                <li>{
     {
     $index}} ---- {
     {
     $value}}</li>    
            {
     {
     /each}}
        </ul>
        `
    let render = template.compile(art);
    let html = render({
     
        arr:['a','b','c']
    })
    console.log("html====>",html);

(二)将模板源代码编译成函数template.compile(source, options);

let art = `
    <ul>
        {
     {
     each user}}
            <li>{
     {
     $index}} ---- {
     {
     $value}}</li>    
        {
     {
     /each}}
    </ul>
    `;
    let html = template.render(art,{
     
        user: {
     
            name:'张三',
            age:100,
            job:'web'
        }
    });
    console.log("html====>",html);

(三)将模板源代码编译成函数并立刻执行template.render(source, data, options);

5.1.5过滤器

注册过滤器以及语法
案例:

template.defaults.imports.map = function(aaa){
     
    switch(aaa){
     
        case 'name':
            return '姓名';
        case 'age':
            return '年龄';
        case 'job':
            return '工作';
    }
}
{
     {
     each arr}}
    <h2>{
     {
     $value.name}}</h2>
     <ul>
        {
     {
     each $value val key }}
            <li>{
     {
     key | map key}} ---- {
     {
     val}}</li>
        {
     {
     /each}}
    </ul>
{
     {
     /each}} 

六、node框架

express 入门比较简单、不好控制
koa 用着比较舒服、async

6.1express

(一)特点: 非破坏式的
(二)中间件: 中间件:中间件功能是可以访问请求对象,响应对象和next应用程序的请求-响应周期中的功能的功能,当调用该功能时,将在当前中间件之后执行中间件;
本人理解: 中间件就是将一个处理程序分成多步来处理,那么每一步,就称之为一个中间件,到了代码里面中间件就是函数;
(三)中间件功能:
①执行任何代码;②更改请求和响应对象;③结束请求-响应周期;调用堆栈中的下一个中间件;
如果当前中间件功能没有结束请求-响应周期,则必须调用next()将控制权传递给下一个中间件功能,否则该请求将被挂起。
中间件为主要的逻辑业务所服务,可分为:应用级中间件、路由级中间件、内置中间件、第三方中间件、错误级中间件。
Node学习(二)_第3张图片
(一) 应用级中间件案例:

const app = require('express')();
//使用next 将会执行继续执行下一个
app.use((req,res,next) => {
     
    console.log('====>>>>',111);
    next()
}); 
app.use((req,res,next) => {
     
    console.log('====>>>>',222);
    next()
});
app.use((req,res) => {
     
    res.send('应用级中间件')
});
app.listen(8080,() => {
     
    console.log(' ----> ','running...');
})

(二)内置中间件—访问静态文件的案例:

const express = require('express');
const app = express();
const path = require('path');

//可以指定多个静态文件的目录
app.use(express.static(path.join(__dirname,'static')))
app.use(express.static(path.join(__dirname,'public')))

//虚拟目录
app.use('/file',express.static(path.join(__dirname,'public')))

app.listen(8080,() => {
     
    console.log(' === >','running...');
})

(三)第三方中间件
①body-parser,将post请求数据解析为对象

const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({
      extended: false }))
//post 数据有两种
//普通的数据
//文件
app.post('/data',(req,res) => {
     
    console.log('req.body====>',req.body)
    res.send('okk');
})

②mysql模块

6.1.1 静态文件

特点: ①可以设置虚拟目录;②可以指定多个静态文件的位置

app.use(express.static('public'));

6.1.2 文件上传

const express = require('express');
const app = express();
const path = require('path');
const multer = require('multer');
const fs = require('fs')

//加载静态文件
app.use(express.static('./static'));
//multer中间件
app.use( multer({
      dest: path.join(__dirname, 'uploads/') }).any() );
//监听
app.listen(8080,() => {
     
    console.log(' === >','running...'); 
})
//post方式文件上传
app.post('/upload',(req,res) => {
     
    // console.log('req.files====>',req.files)
    //旧的路径
    let oldPath = req.files[0].path;
    //extname获取.xxx
    let newPath = req.files[0].path + path.extname( req.files[0].originalname )
    //rename重命名
    fs.rename(oldPath, newPath, err => {
     
        if(err) console.log('err ====>>>>', err);
    })
    res.send('上传成功!!!');
})

6.1.3中间件多重挂载

app.get('/aa', ( req, res, next ) => {
     
    console.log(' ====>>>>', 111111);
    next()
}, ( req, res, next ) => {
     
    console.log(' ====>>>>', 222222);
    next()
}, ( req, res, next) => {
     
    console.log(' ====>>>>', '+++++++++++++++++');
    
    res.send('aa-----------')
    next()
})
app.get('/aa', ( req, res ) => {
     
    console.log(' ====>>>>', 3333333);
    // res.send('bb-----------')前面返回后,后面的就能用了
    res.send(bb)
})

6.1.4 route路由器中间件的跳转

使用route后,直接跳过下一个,到下一个路由

app.get('/aa', ( req, res, next ) => {
     
    console.log(' ====>>>>', 111111);
    next()
}, ( req, res, next ) => {
     
    console.log(' ====>>>>', 222222);
    next('route')
}, ( req, res, next) => {
     
    console.log(' ====>>>>', '+++++++++++++++++');
    
    res.send('aa-----------')
    next()
})
app.get('/aa', ( req, res ) => {
     
    console.log(' ====>>>>', 3333333);
    // res.send('bb-----------')前面返回后,后面的就能用了
    res.send(bb)
})

6.1.5 错误处理中间件

app.use(function (err, req, res, next) {
     
    console.log(' ====>>>>', 4444);
    
    console.error(err.stack)
    res.status(500).send('服务器端错误,请与管理员联系!!')
})

6.1.6 回调数组挂载

let fn1 = (req,res, next) => {
     
    console.log('====>','fn1111');
    next();
};

let fn2 = (req, res, next) => {
     
    console.log('====>','fn2222');

    res.send('fn')
    next();
};
app.get('/bb',[fn1,fn2],(req,res) => {
     
    console.log('====>','fn3333');
})

6.1.7 Application

app.route('/index')
    //全部请求方式
    .all(( req, res, next ) => {
     
        console.log(' ====>>>>', 'all----------');
        next()
    })
    .get(( req, res ) => {
     
        res.send('get index!')
    })
    .post(( req, res ) => {
     
        res.send('post index!')
    })
    .put(( req, res ) => {
     
        res.send('put index!')
    })
    .delete(( req, res ) => {
     
        res.send('delete index!')
    })

6.1.8 模板引擎

app.set('views', path.join(__dirname, 'template')) // specify the views directory  指定视图目录
app.set('view engine', 'art') // register the template engine   注册模板引擎

app.engine('art', template);

app.get('/', function (req, res) {
     
    res.render('index', {
     
        title: 'hello Express!'
    });
});

6.1.9 路由

路由是指应用程序的端点(URL)如何响应客户端请求。

6.2.0异步操作

const express = require('express');
const path = require('path');

let app = express();
//监听
app.listen(8080, (  ) => {
     
    console.log(' ====>>>>', 'express running....');
})
let count = 0;
//关闭默认
app.get('/favicon.ico', ( req, res ) => {
     
    res.send('ok');
    return
})
app.get('/', ( req, res ) => {
     
    res.sendFile(path.join(__dirname, 'static/request.html'))
})
app.get('/index', ( req, res ,next ) => {
     
    if(count>=3){
     
        res.status(500).send('请求次数过多,请稍后重试!!');
    }
    next();
    if(req.bool){
     
        count++;
    }
})
app.get('/index', ( req, res ) => {
     
    let random = Math.random() * 10;
    setTimeout(() => {
     
        if(random > 5){
     
            res.send(`'request'${
     random}大于5`)
            req.bool = true;
        }else{
     
            res.send(`'request'${
     random}  < 5`)
        }
    },100)
})

七、koa

安装: npm i koa -S

koa@1 Generator
koa@2 Generator/Async
koa@3 Async

7.1 特点

(1)没有任何的内置中间件;(2)功能部分交给第三方中间件;
ctx.request 封装好
ctx.req 原本的请求对象

安装: npm install koa-simple-router
需要静态文件需要安装: npm i koa-static -S
安装路由: npm i koa-simple-router -S

const Koa = require('koa');
const app = new Koa;
const path = require('path');
//处理数据的路由
const router = require('koa-simple-router');
//文件上传需要的路由
const koaBody = require('koa-better-body');
const convert = require('koa-convert');
//自带的静态
const static = require('koa-static');


//指定上传目录
app.use(convert(koaBody({
     
    uploadDir: path.join(__dirname,'uploads'),
    //文件名
    keepExtensions: true
})));


//路由
app.use(router(_ => {
     
    _.get('/', (ctx, next) => {
     
      ctx.body = 'hello node'
    })
    //get 数据处理
    _.get('/index', (ctx, next) => {
     
        console.log('ctx.request.query ===>>>>',ctx.request.query);
        ctx.body = 'ok'
    })

    /* 
        普通的post数据
        文件
    */
    _.post('/index', (ctx, next) => {
     
        // ...
        console.log('ctx.request.files', ctx.request.files);
        console.log('ctx.request.fields', ctx.request.fields);
        ctx.body = 'post ok'
    })
  })
)

//静态文件
app.use(static(path.join( 'static')));

// app.use((ctx, next) => {
     
//     console.log("ctx--->", ctx);
//     next();
// })

//监听器
app.listen(8080,() => {
     
    console.log('sunning...');
})

注意: enctype="multipart/form-data
不对字符编码,或在使用包含文件上传控件的表单时,必须使用该值。

node学习(三)

你可能感兴趣的:(Node,nodejs)