美文网首页
原生Node.js的一些重要内容总结

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

作者: Yytg | 来源:发表于2017-12-30 21:07 被阅读27次

原生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');

相关文章

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

    原生Node.js的一些重要内容总结 1.数据交互 2.流(stream) 3.压缩(zlib) 4.管道操作(p...

  • Node.js常用的内置模块

    常用的内置模块(path,fs,url,querystring,) Node.js中提供了一些原生的模块,我们称之...

  • node.js一些自己的理解

    express是基于node.js的一个框架,保留了一些nodejs原生的api并且新增了一些api app=ex...

  • 2017/3/27

    总结一下关于date的一些静态方法: 原生: moment.js

  • Ajax Axios

    关于Ajax兼容性问题 前端原生Ajax(get方式),后端使用node.js 前后端代码: 前端原生Ajax(p...

  • 2019-12-19

    # Node.js 第1天 ## 上午总结 - Node.js 是什么 + JavaScript 运行时 + ...

  • 原生node.js

    一、起步 二、事件驱动程序 // 绑定事件及事件的处理程序eventEmitter.on('eventName',...

  • 深入node.js内部原理

    Node.js 探秘:初识单线程的 Node.js 第二遍总结 Node.js通过libuv来处理与操作系统的交互...

  • ReentrantLock

    阅读了ReentrantLock的源码,简单总结了一些实现上的要点如下: synchronized是Java原生的...

  • 前端必须学会的5个原生JavaScript对象方法

    前端必须学会的5个原生JavaScript对象方法 JavaScript 随着node.js和基于JavaScri...

网友评论

      本文标题:原生Node.js的一些重要内容总结

      本文链接:https://www.haomeiwen.com/subject/fipngxtx.html