原生Node.js的一些重要内容总结

2017-12-30  本文已影响27人  Yytg

原生Node.js的一些重要内容总结

1.数据交互

2.流(stream)

3.压缩(zlib)

4.管道操作(pipe)

5.接口管理(Router)

6.Cluster(,集群(多进程)

7.crypto(加密)

1.数据交互

常见的三种数据交互方式:

1.GET方式:

js:
const http = require('http');
const url = require('url');
http.createServer((req,res)=>{
  let {pathname,query} = url.parse(req.url,true);
  console.log('接收了get请求',pathname,query);
  res.end();
}).listen(8080);

html:
<form action="http://localhost:8080" method="get">
  用户:<input type="text" name='user'/><br>
  密码:<input type="password" name="pass"><br>
  <input type="submit" name="sub" value="提交">
</form>

2.POST(urlencoded)

js:
// node.js数据交互
const http = require('http');
const url = require('url');
const querystring = require('querystring');
let server = http.createServer((req,res)=>{
  // post请求 urlencoded
  let aBuffer = [];
  req.on('data',data=>{
    aBuffer.push(data);
  });
  req.on('end',()=>{
    let data = Buffer.concat(aBuffer);
    let datas = querystring.parse(data.toString());
    console.log(datas);
  })
});
server.listen(8080,()=>{
  console.log('this server running 8080 port');
});
html:
<form action="http://localhost:8080" method="post" enctype="application/x-www-form-urlencoded">
  用户:<input type="text" name='user'/><br>
  密码:<input type="password" name="pass"><br>
  <input type="submit" name="sub" value="提交">

3.POST(form-data)

html:
<form action="http://localhost:8080/login" method="post" enctype="multipart/form-data">
  用户: <input type="text" name="user" /><br>
  密码: <input type="password" name="pass"><br>
  <input type="file" name="f1" value="选择"><br>
  <input type="file" name="f2" value="选择"><br>
  <input type="file" name="f3" value="选择"><br>
  <input type="submit" value="注册">

这种方式得到的数据要进行判断处理才可以,因为还涉及文件的上传。
而得到的数据是Buffer,它是二进制数据。所以要处理二进制数据。得到的Buffer格式为:

------WebKitFormBoundaryq9dAWVB72Rj30S9c
Content-Disposition: form-data; name="user"

blue
------WebKitFormBoundaryq9dAWVB72Rj30S9c
Content-Disposition: form-data; name="pass"

123456
------WebKitFormBoundaryq9dAWVB72Rj30S9c
Content-Disposition: form-data; name="f1"; filename="1.txt"
Content-Type: text/plain

aaa
bbb
ccc
------WebKitFormBoundaryq9dAWVB72Rj30S9c--

处理代码如下:

// node.js数据交互
const http = require('http');
const url = require('url');
const querystring = require('querystring');
const common = require('./libs/common');
const fs = require('fs');
const uuid = require('uuid/v4');
const path = require('path');

let server = http.createServer((req,res)=>{
  let aBuffer = [];
  req.on('data',data=>{
    aBuffer.push(data);
  });
  req.on('end',()=>{
    let data = Buffer.concat(aBuffer);
    if(req.headers['content-type'].startsWith('multipart/form-data')){ //file
      let post = {};
      let files = {};
      // 提取分隔符
      const boundary = '--'+req.headers['content-type'].split('; ')[1].split('=')[1];
      //console.log(boundary);
      // 分割符切分
      let arr = data.split(boundary);
      //console.log(arr.map(item=>item.toString()));
      // 扔掉头尾(<>、<--\r\n>)
      arr.shift();
      arr.pop();
      // 每一项处理
      // 每一项的头尾扔掉(\r\n....\r\n)
      arr = arr.map(item=>item.slice(2,item.length-2));
      // 找到第一个'\r\n\r\n',切开,一半信息,一半数据
      arr.forEach(item=>{
        let n = item.indexOf('\r\n\r\n');
        let info = item.slice(0,n);
        let data = item.slice(n+4);
        info = info.toString();
       //  console.log(infor);
        let total = 0;
        let complete = 0;
        if(info.indexOf('\r\n')==-1){ //只有一行信息 普通数据
          let key = common.parseInfo(info).name;
          info = info.toString();
          post[key] = data;
        }else{                        // 两行数据 文件
          total++;
          let json = common.parseInfo(info);
          let key = json.name;
          let filename = json.filename;
          console.log(json);
          console.log(filename);
          let type = json['content-type'];
          let filepath = `upload/${uuid().replace(/\-/g,'')}${path.extname(filename)}`;
          files[key] = {filename,type,filepath};
          fs.writeFile(filepath,data,err=>{
            if(err){
              console.log('文件写入失败');
            }else{
              console.log('写入成功');
              complete++;
              console.log(post,files);
            }
          });
        }
      })
    }else{ // urlencoded
      let post = querystring.parse(data.toString());
      console.log(post);
    }
  })
});
server.listen(8080,()=>{
  console.log('this server running 8080 port');
});
-------------------------------------------------------------------------------------------------
common.js:
Buffer.prototype.split = Buffer.prototype.split||function(spliter){
  let b1 = this;
  let result = [];
  let n;
  while((n=b1.indexOf(spliter))!=-1){
    let res1 = b1.slice(0,n);
    let res2 = b1.slice(n+spliter.length);
    result.push(res1);
    b1 = res2;
  }
  result.push(b1);
  return result;
}
exports.parseInfo = function(str){
  let arr = str.split('; ');
  let arr2 = [];
  arr.forEach(item=>{
    let a = item.split('\r\n');
    arr2 = arr2.concat(a);
  });
  let json = {};
  arr2.forEach(s=>{
    let [key,val] = s.split('=');
    if(!val){
      json[key] = val;
    }else{
      json[key] = val.substring(1,val.length-1);
    }
  });
  return json;
}


2.流(stream)和管道操作

真正的数据传输肯定要转为流的方式进行传输,它可以减少内存占用、增强系统性能(利用率高)。
流的传输方式是读一块,发一块。
分为读取流,写入流,读写流(压缩,加密就是读取流)。

读取流:request,fs.createReadStream.
写入流:response,fs.createWriteStream.

onst fs = require('fs');
const zlib = require('zlib');
let gz = zlib.createGzip();
let rs = fs.createReadStream('www/1.html'); // 创建读取流
let ws = fs.createWriteStream('www/2.html.gz'); // 创建写入流
rs.pipe(gz).pipe(ws); // 管道操作

4.压缩(zlib)

数据必须进行压缩处理,再进行传输。在Node.js中它是配合流和管道一起使用的。

5.接口管理(Router)

创建EventEmitter对象:EventEmitter 可以模拟一个事件队列(相应的监听与触发)

const Event = require('events').EventEmitter; // EventEmitter 模拟一个事件队列
let ev = new Event();

// 监听
ev.on('clearboy',function(a,b,c,d){
  console.log('收到1个事件',a,b,c,d);
})
ev.on('clearboy',function(a,b,c,d){
  console.log('收到2个事件',a,b,c,d);
})
// 触发
let a = ev.emit('clearboy',1,2,3,4);
console.log(a)   // true

既有监听又有触发,则返回的结果为a为true,否则为false,以此判断是接口还是普通的文件读取.

const http = require('http');
const url = require('url');
const router = require('./libs/router');
const user = require('./routers/user');
const fs = require('fs');
const zlib = require('zlib');

http.createServer((req,res)=>{
  let { pathname, query } = url.parse(req.url,true);
  req.query = query;
  res.send = function(data){
    if(!(data instanceof Buffer) && typeof data!='string'){ // 如果不是buffer和string
      data = JSON.stringify(data);
    }
    res.write(data);
  }
  //不是接口
  if(router.emit(pathname,req ,res)==false){
 //读取文件
  res.setHeader('Content-Encoding','gzip');
   let rs = fs.createReadStream(`www${pathname}`);
   let gz = zlib.createGzip();
   rs.pipe(gz).pipe(res);
   rs.on('error',err=>{
     res.writeHeader(404);
     res.write('not found');
     res.end();
   });
  }else{  // 是接口

  }
}).listen(8080);
-------------------------------------------------------------------------------------------------
user.js:
let router = require('../libs/router');
// 用户登录注册接口
let users = {};
router.on('/login',(req,res)=>{
  let {user,pass} = req.query;
  if(!users[user]){
    res.send({code:'1',msg: '用户名不存在'});
    res.end();
  }else if(users[user]!=pass){
    res.send({code:'1',msg: '用户登录密码错误'});
    res.end();
  }else{
    res.send({code:'0',msg:'登录成功'});
    res.end();
  }
});
router.on('/reg',(req,res)=>{
  let {user,pass} = req.query;
  if(users[user]){
    res.send({code:'1',msg: '用户已存在'});
    res.end();
  }else{
    users[user] = pass;
    res.send({code:'0',msg: '注册成功'});
    res.end();
  }
})
router.js:
let Event = require('events').EventEmitter;
module.exports = new Event();

6.Cluster(集群(多进程))

//多进程
const cluster = require('cluster');
const http = require('http');
const url = require('url');
const fs = require('fs');
const numCups = require('os').cpus().length;
const process = require('process');

if(cluster.isMaster) {
  console.log(`主进程${process.pid}正在运行`);
  // 创建子进程
  for(let i=0; i<numCups;i++){
    cluster.fork();
  }
}else{
  http.createServer((req,res) => {
    res.writeHeader(200);
    res.write('hello world\n')
  }).listen(8080);
  console.log(`${process.pid}进程正在运行`);
}

7.crypto(加密)

const crypto = require('crypto');
let md5 = crypto.createHash('md5');
md5.update(pass);
pass = md5.digest('hex');
上一篇 下一篇

猜你喜欢

热点阅读