//创建可读流 __dirname当前文件
let readable = fs.createReadStream(path.join(__dirname,'xxxxx'));
//可写流
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('====>',"读完了");
});
当在可读流上调用 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 install xxxx -g
本地安装位置:npm root -g
本地安装:
–save 生产依赖 vue jQuery
–save-dev 开发依赖 webpack、 less
例:npm i less --save-dev
安装:npm i -g nodemon
使用:nodemon xxx.js
①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文档。
art-template是一个简约的、超快的模板引擎
它采用作用域预声明的技术来优化模板渲染速度,从而获得接近JavaScript极限的运行性能,并且同时支持NodeJS和浏览器
(一)拥有接近JavaScript渲染极限的性能
(二)调试友好:语法、运行时错误日志精确到模板所在行;支持在模板文件上打断点
(三)支持Express、Koa、Webpack
(四)支持模板继承与子模板
(五)浏览器版本仅6KB大小
art-template 同时支持两种模板语法。标准语法可以让模板更容易读写;原始语法具有强大的逻辑处理能力。
标准语法:
{
{
if user}}
<h2>{
{
user.name}}</h2>
{
{
/if}}
原始语法:
<% if (user) {
%>
<h2><%= user.name %></h2>
<% } %>
var template = require('art-template');
var html = template(__dirname + '/tpl-user.art', {
user: {
name: 'aui'
}
});
(一)基于模板名渲染模板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);
注册过滤器以及语法
案例:
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}}
express 入门比较简单、不好控制
koa 用着比较舒服、async
(一)特点: 非破坏式的
(二)中间件: 中间件:中间件功能是可以访问请求对象,响应对象和next应用程序的请求-响应周期中的功能的功能,当调用该功能时,将在当前中间件之后执行中间件;
本人理解: 中间件就是将一个处理程序分成多步来处理,那么每一步,就称之为一个中间件,到了代码里面中间件就是函数;
(三)中间件功能:
①执行任何代码;②更改请求和响应对象;③结束请求-响应周期;调用堆栈中的下一个中间件;
如果当前中间件功能没有结束请求-响应周期,则必须调用next()将控制权传递给下一个中间件功能,否则该请求将被挂起。
中间件为主要的逻辑业务所服务,可分为:应用级中间件、路由级中间件、内置中间件、第三方中间件、错误级中间件。
(一) 应用级中间件案例:
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模块
特点: ①可以设置虚拟目录;②可以指定多个静态文件的位置
app.use(express.static('public'));
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('上传成功!!!');
})
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)
})
使用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)
})
app.use(function (err, req, res, next) {
console.log(' ====>>>>', 4444);
console.error(err.stack)
res.status(500).send('服务器端错误,请与管理员联系!!')
})
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');
})
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!')
})
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!'
});
});
路由是指应用程序的端点(URL)如何响应客户端请求。
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)
})
安装: npm i koa -S
koa@1 Generator
koa@2 Generator/Async
koa@3 Async
(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学习(三)