二十、node.js

69 阅读5分钟

1. node.js

1.1 node.js是什么

JavaScript语言的服务器运行环境

1.2 node.js的特点

  • ① 单线程
  • ② 非阻塞 I/O 事件驱动

安装了nodejs,会带一些内置的模块:fs、http、path、url、events、querystring...

2. http模块的使用

1. 通过require导入http模块。这里的require相当于import、script标签的src属性
const http = require('http');

2. 创建服务。 req:请求报文  res:响应报文
let server = http.createServer((req,res)=>{
    if(req.url=='/favicon.ico'){
        return;
    }
    console.log(req.url);
    console.log('浏览器携带参数 age=20 给服务器');
    
    // 设置响应头和响应编码(告诉浏览器,我给你的数据如何解析)
    res.writeHead({'Content-Type':'text/html;charset=utf-8'});
    res.end('服务器响应给浏览器的数据'); // 注意:响应数据后必须用res.end断开连接(http请求具有短连接的特点)
})

3. 配置端口 (一个端口只能分配给一个线程)
server.listen(8081,function(){
    console.log('服务器启动完毕');
})

3. fs模块的使用

3.1 fs.stat() 文件? 文件夹?

  • 配合stats.isFile()和stats.isDirectory()异步的检测是否为文件?是否为文件夹?

    const fs = require('fs'); // 导入fs模块
    fs.stat('./aaa文件夹',function(err,stats){
        if(err){
            console.log(err);
            return;
        }
        console.log(stats.isFile());
        console.log(stats.isDirectory());
    })
    

3.2 fs.statSync() 文件? 文件夹?

  • 配合stats.isFile()和stats.isDirectory()同步的检测是否为文件?是否为文件夹?

    const fs = require('fs'); // 导入fs模块
    let stats = fs.statSync('./aaa文件夹');
    console.log(stats.isFile());
    console.log(stats.isDirectory());
    

3.3 fs.mkdir() 创建文件夹

  const fs = require('fs'); // 导入fs模块
  fs.mkdir('./aaa文件夹',function(err){
      if(err){
          console.log('创建文件夹失败');
          return;
      }
      console.log('创建文件夹成功');
  })

3.4 fs.rmdir() 删除文件夹

  const fs = require('fs'); // 导入fs模块
  fs.rmdir('./aaa文件夹',function(err){
      if(err){
          console.log('删除文件夹失败');
          return;
      }
      console.log('删除文件夹成功');
  })

3.5 fs.readdir() 读取文件夹

  const fs = require('fs'); // 导入fs模块
  fs.readdir('./aaa文件夹',function(err,files){
      if(err){
          console.log('读取文件夹失败');
          return;
      }
      console.log('读取文件夹成功');
      console.log(files); // files是string[],支持forEach
  })

3.6 fs.appendFile() 写入文件并创建文件(追加文件内容,不覆盖文件内容)

const fs = require('fs'); // 导入fs模块
fs.appendFile('./aaa文件夹/a.txt','我是通过appendFile追加的内容',function(err){
    if(err){
        console.log('写入内容失败');
        return;
    }
    console.log('写入内容成功');
})

3.7 fs.writeFile() 写入文件并创建文件(覆盖文件内容)

const fs = require('fs'); // 导入fs模块
fs.writeFile('./aaa文件夹/a.txt','我是通过writeFile添加的内容',function(err){
    if(err){
        console.log('写入内容失败');
        return;
    }
    console.log('写入内容成功');
})

3.8 fs.unlinkFile() 删除文件

const fs = require('fs'); // 导入fs模块
fs.unlinkFile('./aaa文件夹/a.txt',function(err){
    if(err){
        console.log('删除文件失败');
        return;
    }
    console.log('删除文件成功');
})

3.9 fs.readFile() 读取文件内容

const fs = require('fs'); // 导入fs模块
fs.readFile('./aaa文件夹/a.txt','utf-8',function(err,data){
    if(err){
        console.log('读取文件失败');
        return;
    }
    console.log('读取文件成功');
    console.log(data); // 如果不传参数'utf-8',data默认数据类型是Buffer,
    // 可以通过传参数'utf-8'把data编译成字符串,也可以通过data.toString()转换为字符串
})

3.10 fs.createReadStream() 读取流 fs.createWriteStream() 写入流

  • 适用于大文件的读写,需要chunk,利用data事件和end事件一步一步的小口读取/写入

    【案例:将大文件a.txt的内容写到b.txt中】
    const fs = require('fs'); // 导入fs模块
    const read = fs.createReadStream('./a.txt');
    const write = fs.createReadStream('./b.txt');
    
    read.on('data',function(chunk){ // chunk是Buffer数据类型
        write.write(chunk.toString()); // 读取一次,写入一次
    })
    read.on('end',function(){
        write.end();
    })
    write.on('finish',function(){
        console.log('所有的事情都做完了');
    })
    
    【案例:将小文件a.txt的内容写到b.txt中】
    const fs = require('fs'); // 导入fs模块
    const read = fs.createReadStream('./a.txt');
    const write = fs.createReadStream('./b.txt');
    
    read.pipe(write);
    

4. url模块的使用

4.1 url.parse() 将字符串url解析成对象

  const url = require('url'); // 导入url模块
  let str = 'http://127.0.0.1:8056/login?name=小刘&age=20';
  console.log(url.parse(str,true)); // 将url字符串解析成对象。
  // 如果第2个参数不写,query是键值对字符串,如果第2个参数为true,query被解析成对象
  

【补充】手动将query键值对字符串转换为对象

  const url = require('url'); // 导入url模块
  let str = 'http://127.0.0.1:8056/login?name=小刘&age=20';
  let query = url.parse(str).query
  let arr = query.split('&');
  for(let i = 0;i < arr.length; i++){
      let key = arr.split('=')[0];
      let val = arr.split('=')[1];
      obj[key] = val;
  }
  console.log(obj);

4.2 url.format() 将对象转换成url字符串

const url = require('url'); // 导入url模块
let str = 'http://127.0.0.1:8056/login?name=小刘&age=20';
console.log(url.format(url.parse(str)));

5. http模块的使用

1. 导入模块
const http = require('http');

2. 创建服务
let server = http.createServer((req,res)=>{ // req:请求报文   res:响应报文
    if (req.url == "/favicon.ico") {
        return;
    }
    console.log(req.url);
    
    // 设置响应头,告诉浏览器我给你的数据如何解析
    res.setHeader('Content-Type','text/html;charset=utf-8');
    res.write('服务器给浏览器响应一些数据');
    res.end('也可以直接在这里写入响应的数据'); // res.end() 必须要写,因为http协议是短连接。res.end()后面不能再有代码,否则会报错(一般在res.end()后面加return可以解决此问题)。
})

3. 配置端口 (一个端口只能分配给一个线程)
server.listen(8082,function(){
    console.log('服务器启动成功!')
})

6. events模块的使用

  • 实现了一个发布订阅模式,通过on方法订阅,通过emit实现发布

    const Events = require('events'); // 导入events模块
    class MyEvents extends Events {}; // 继承
    const e = new MyEvents(); // 创建实例对象
    
    1. on订阅 ---> 绑定事件
    let fens1 = function(str){
      console.log('pdd对fens1说:'+str);
    }
    let fens2 = function(str){
          console.log('pdd对fens2说:'+str);
    }
    let fens3 = function(str){
          console.log('pdd对fens3说:'+str);
    }
    e.on('pdd',fens1);
    e.once('pdd',fens2); // once 只会触发一次
    e.on('pdd',fens3);
    e.off('pdd',fens3); // off 解绑
    
    2. emit发布 ---> 触发事件
    e.emit('pdd','家人们刷点礼物');
    

7. path模块的使用

7.1 path.extname() 获取文件的扩展名

 const path = require('path');  // 导入path模块
 console.log(path.extname('./get请求.js')); // .js

7.2 path.basename() 获取文件/文件夹的名称

7.3 path.dirname() 获取文件/文件夹的路径

【注意】结果不包括当前的文件/文件夹的名称

7.4 path.join() 拼接

 console.log(path.join('aaa/bbb/','ccc/ddd')); // aaa\bbb\ccc\ddd
                                               // path.join()拼接路径

7.5 path.resolve() 拼接或替换。 第2个参数开始位置 / 就是替换,其他情况是拼接

 console.log(path.resolve('aaa/bbb/','ccc/ddd')); // E:aaa\bbb\ccc\ddd
                                                  // path.resolve()拼接后处理成一个绝对路径
 console.log(path.resolve('aaa/bbb/','/ccc/ddd'));  // E:\ccc\ddd

【补充】path.join()和path.resolve()的区别

8. process模块的使用

  • 在使用的时候可以不用导入process模块

8.1 process.arch 得到你的系统是X64还是X32

 console.log(process.arch); // X64

8.2 process.evn.PATH 环境变量

 console.log(process.evn.PATH);

8.3 process.evn.LANG 操作系统的语言

 console.log(process.evn.LANG);

9. querystring模块的使用

9.1 qs.parse() 把字符串转换为对象

const qs = require('querystring'); // 导入querystring模块
const str = 'name=A&age=20&sex=男&hobby=钱&hobby=运动';
qs.parse(str);

9.2 qs.stringify() 把对象转换为字符串

const qs = require('querystring'); // 导入querystring模块
const str = 'name=A&age=20&sex=男&hobby=钱&hobby=运动';
qs.parse(str);