Node.js学习笔记

什么是Node.js

Node.js可以解析Js代码(没有浏览器安全级别的限制)提供很多系统级别的API,如:
-文件的读写
-进程的管理
-网络通信

开发环境配置

下载:https://nodejs.org/en/
确认Node环境是否安装成功
查看node的版本号:

node --version或者node -v

模块/包/与CommonJS

在这里插入图片描述

1、文件读写

/*
**fs是file-system的简写,就是文件系统的意思
**例如 fs.readFile就是用来读取文件的
*/
const fs = require('fs');
//writeFile存在文件则进行覆盖,不存在则创建
fs.writeFile('./log.txt','hello',(err,data)=>{
    if(err){
        console.log('文件创建失败');
    }else{
        console.log('文件创建成功');
    }
})
//readFile异步读取只能读取文件
fs.readdir('./',(err,data)=>{
    if(err){
        console.log(err.Error);
    }else{
        console.log('文件读取成功');
    }
})

2、进程的管理(Process)

console.log(process.argv.slice(2));

3、网络通信

//引入http模块
const http = require('http');

//创建一个HTTP服务器 request:请求对象 response:响应对象
const server = http.createServer((request,response)=>{
    let url = request.url;
    response.write(url);
    response.end();
})

server.listen(8090,'localhost',()=>{
    console.log('localhost:8090')
})

4、URL

const url = require('url');
const  querystring = require('querystring');

const urlString = 'https://www.cnblogs.com/xiongdongdong/p/11398466.html?id=6';

//url.parse()解析地址获取具体信息
console.log(url.parse(urlString));

//url.formeat()将一个解析后的URL对象、转成、一个格式化的URL字符串
let formeat = {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'www.cnblogs.com',
    port: null,
    hostname: 'www.cnblogs.com',
    hash: null,
    search: '?id=6',
    query: 'id=6',
    pathname: '/xiongdongdong/p/11398466.html',
    path: '/xiongdongdong/p/11398466.html?id=6',
    href: 'https://www.cnblogs.com/xiongdongdong/p/11398466.html?id=6'
  }
  console.log(url.format(formeat));

//url.resolve()替换 域名后面第一个“/”后的内容
let a = url.resolve('/one/two/three', 'four') ,
b = url.resolve('http://example.com/', '/one'),
c = url.resolve('http://example.com/one', '/two');
console.log(a +","+ b +","+ c);
/*
querystring模块用于解析与格式化url查询字符串
它提供了四个方法,分别是:querystring.parse, querystring.stringify, querystring.escape和querystring.unescape;
*/

// 1、querystring.parse(string, separator, eq, options),该方法是将一个字符串反序列化为一个对象。
// string: 指需要反序列化的字符串;
// separator(可选): 指用于分割字符串string的字符,默认为 &;
// eq(可选): 指用于划分键和值的字符和字符串,默认值为 "=";
// options(可选): 该参数是一个对象,里面可设置 maxKeys 和 decodeURIComponent 这两个属性。
console.log(querystring.parse(formeat.query));

// 2、querystring.stringify(obj, separator, eq, options),该方法是将一个对象序列化成一个字符串。
// 参数:obj指需要序列化的对象;
// separator(可选),用于连接键值对的字符或字符串,默认为 &;
// eq(可选),用于连接键和值的字符或字符串,默认值为 "=";
// options(可选),传入一个对象,该对象设置 encodeURIComponent这个属性;
console.log(querystring.stringify(formeat));

//3、querystring.escape(str)escape该方法可使传入的字符串进行编码
const char = "name=小明&sex=男";
const res = querystring.escape(char);
console.log(res);  // 输出 name%3D%E7%A9%BA%E6%99%BA%26sex%3D%E7%94%B7

//4、querystring.unescape(str)该方法是对 使用了 escape编码的字符进行解码
const res2 = querystring.unescape(res);
console.log(res2); // name=空智&sex=男

5、爬虫案例练习

//引入http模块
const http = require('http');
//引入https模块
const https = require('https');
//引入cheerio模块
const cheerio = require('cheerio');

//待爬取的地址目标
let url = 'https://www.lagou.com/';

//对html数据做处理
const filterMenu = (html)=>{
    let $ = cheerio.load(html);
    let menu = $('.menu_main');
    let menuData = [];
    menu.each((index,value)=>{
        //获取一级菜单
        let menuTitle = $(value).find('h2').text();
        //获取二级菜单
        let menuList = $(value).find('a'); 
        let menuLists = [];
        menuList.each((index,value)=>{
            menuLists.push($(value).text());
        })
        menuData.push({
            menuTitle:menuTitle,
            menuList:menuLists
        })
    })
    return menuData
}

//打印回显
const printMenu = (menu)=>{
    menu.forEach((value)=>{
        console.log(value.menuTitle+'\n');
        value.menuList.forEach((value)=>{
            console.log(value);
        })
    })
}


https.get(url,(res)=>{
    let html = '';
    res.on('data',(data)=>{
        html += data
    })

    res.on('end',()=>{
        // console.log(html);
        let result = filterMenu(html);
        printMenu(result);
    })
    res.on('error',(err)=>{
        console.log(err);
    })
})

6、Http Request

const { response } = require('express');
const https = require('https');
let options = {
    hostname:'douban.uieee.com',
    port:443,
    method:"GET",
    path:'/v2/movie/coming_soon'
}

let request = https.request(options,(response) => {
    console.log(response);
})

request.on('error',(err) => {
    console.log(err);
})

request.end();

7、流应用

为什么要需要流?
当我们学习新知识的时候,首先我们知道为什么要学习,那我们为什么要学习流?因为在在node中读取文件的方式有来两种,一个是利用fs模块,一个是利用流来读取。如果读取小文件,我们可以使用fs读取,fs读取文件的时候,是将文件一次性读取到本地内存。而如果读取一个大文件,一次性读取会占用大量内存,效率很低,这个时候需要用流来读取。流是将数据分割段,一段一段的读取,可以控制速率,效率很高,不会占用太大的内存。gulp的task任务,文件压缩,和http中的请求和响应等功能的实现都是基于流来实现的。因此,系统学习下流还是很有必要的

const fs = require('fs');
/*
流都是基于原生的fs操作文件的方法来实现的,通过fs创建流。所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:
open -打开文件
data -当有数据可读时触发。
error -在读收和写入过程中发生错误时触发。
close -关闭文件
end - 没有更多的数据可读时触发
*/
//createReadStream 为可读流 createWriteStream为可读写流
let fileReadStream = fs.createReadStream('data.json',{
        highWaterMark:3, //文件一次读多少字节,默认 64*1024
        flags:'r', //默认 'r'
        autoClose:true, //默认读取完毕后自动关闭
        start:0, //读取文件开始位置
        end:3, //流是闭合区间 包含start也含end
        encoding:'utf8' //默认null
});

let count = 0;

//监听数据变化
fileReadStream.on('data',(chunk) => {
    console.log(`${++count} 接收到:${chunk.length}`);
})

//在读收和写入过程中发生错误时触发
fileReadStream.on('error',(err) => {
    console.log(err);
})

//读取结束时触发
fileReadStream.on('end',() => {
    console.log('结束了')
})

8、node创建后端路由

const http = require('http');
const url = require('url');
//引入路由文件
let router = require('./router_1');
//创建http服务器
http.createServer((req,res) => {
 /*
向请求的客户端发送响应头。
该函数在一个请求内最多只能调用一次,如果不调用,则会自动生成一个响应头。
*/
    res.writeHead(200,{'Content-Type':'text/html; charset=utf-8'});
    if(req.url !== '/favicon.ico'){
        let pathName = url.parse(req.url).pathname.replace(/\//,'');
        try{
            router[pathName](req,res); 
        }catch{
            router['home'](req,res);
        }

    }
    res.end();

}).listen(3000);
console.log('Server running at http://localhost:3000');  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值