NodeJS--01

2020-07-13  本文已影响0人  幸之石

前端框架的发展历史

学习资源推荐

Node.js基础

1、Node.js介绍

编译型
解释型

为什么要学习node.js?

什么是Node.js?

Node.js 是一个基于 Chrome V8 引擎的 JavaScript运行环境。
Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。

Node.js 可以解析JS代码(没有浏览器安全级别的限制),提供很多系统级别的API,如fs/net/process/os等。

什么是NPM?

Node.js 的包管理器 npm,成为世界上最大的开放源代码的生态系统。

学习资源推荐

2、Node.js安装

版本识别:

12.3.2

下载安装:

node -v
npm -v

nvm安装

nvm -v 
nvm list
nvm install 版本号
nvm use 版本号

Node.js内置模块

1、URL模块

url.parse('http://www.baidu.com:8080/api?user=cyr&pwd=123#100')
url.parse('http://www.baidu.com:8080/api?user=cyr&pwd=123#100', true)

// 把URL解析成对象
url.parse('://www.baidu.com:8080/api?user=cyr&pwd=123#100', true, true)
    {
        protocol: 'http:',
        slashes: true,
        auth: null,
        host: 'www.baidu.com:8080',
        port: '8080',
        hostname: 'www.baidu.com',
        hash: '#100',
        search: '?user=cyr&pwd=123',
        query: 'user=cyr&pwd=123',
        pathname: '/api',
        path: '/api?user=cyr&pwd=123',
        href: 'http://www.baidu.com:8080/api?user=cyr&pwd=123#100'
    }

// 把对象格式化成URL
url.format({
    protocol: 'http:',
    slashes: true,
    auth: null,
    host: 'www.baidu.com:8080',
    port: '8080',
    hostname: 'www.baidu.com',
    hash: '#100',
    search: '?user=cyr&pwd=123',
    query: 'user=cyr&pwd=123',
    pathname: '/api',
    path: '/api?user=cyr&pwd=123',
})

// 把两段URL片段,组合成一个完整的URL
url.resolve('http://www.baidu.com', '/api/getList')

2、QueryString模块

querystring.stringify()

// 默认使用 & 进行分隔,键值用 = 连接
querystring.stringify({
    name: 'qf',
    course: ['nodejs', 'vue', 'react']
})

// 自定义分隔符
querystring.stringify({
    name: 'qf',
    course: ['nodejs', 'vue', 'react']
}, ',')

// 自定义键值对之间的分隔符
querystring.stringify({
    name: 'qf',
    course: ['nodejs', 'vue', 'react']
}, ',', ':')  

querystring.parse() // querystring.stringify()的逆方法,也可以接受后面的两参数

querystring.escape('北京')

querystring.unescape() // 与querystring.escape互逆

3、HTTP/HTTPS 模块 - get()

目标:实现一个HTTP爬虫

需求讲解:
打开拉勾网 https://www.lagou.com
我们的目标是抓取到了一级品类和二级品类的内容
审查元素,分析其源码结构

第一步:抓取首页源码字符串
    https.get(url, fn)
    用于抓取页面中的静态内容和数据

第二步:使用 cheerio 进一步处理源码字符串,获取到品类名称
    ```
    npm install cheerio -D
    ```
第三步:在控制台上打印出我们获取到的品类名称
var https = require('https');
var cheerio = require('cheerio');
var html = ""
https.get('https://www.lagou.com/',function(res){
    res.on('data',function(str){
        html+=str;
    })
    res.on('end',function(){
        getMenu(html)
    })
    res.on('error',function(err){
        console.log(err)
    })
})

function getMenu(str){
    var $ = cheerio.load(str);
    var cates = [];
    $('.mainNavs').find('.menu_box').each(function(index,item){
        var cate = {
            title:"",
            list:[]
        }
        cate.title = $(item).find('h2').text().replace(/[\\n\s]/g,'');
        $(item).find('h3').each(function(index,item){
            cate.list.push($(item).text())
        })
        cates.push(cate)
    })
    console.log(cates)
}

4、HTTP/HTTPS 模块 - request()

目标:获取cnode开放数据

https.request() 

cnode的api接口文档:https://cnodejs.org/api

GET 的请求方式
    demo:从cnode开放平台获取文章列表

POST 的请求方式
    demo:执行cnode开放平台上的文件收藏功能
var https = require('https')

var options = {
  hostname: 'cnodejs.org',
  port: '443',
  method: 'GET',
  path: '/api/v1/topics?limit=1'
}

var req = https.request(options, function(res) {
  // res.setEncoding('utf8')
  var str = ''
  res.on('data', function(data) {
    str += data
  })
  res.on('end', function() {
    // 解析为JSON格式
    var res = JSON.parse(str)
    if (res.success) {
      console.log(res.data)
    }
  })
})

req.on('error', function(err) {
  console.log(err)
})

req.end()
var https = require('https')
var qs = require('querystring')

// 把对象转化成可提交的字符串序列
var data = qs.stringify({
  topic_id: '5ee1ee83b703280f0bcb922a',
  _csrf: 'J5pSyVpb-DPf18zuVRoeoRa3YtjiTrDmSbow'
})

// 从cnode控制台复制这些内容
var options = {
  hostname: 'cnodejs.org',
  port: '443',
  method: 'POST',
  path: '/topic/collect',
  headers: {
    "Accept": "application/json, text/javascript, */*; q=0.01",
    "Accept-Encoding": "gzip, deflate, br",
    "Accept-Language": "zh-CN,zh;q=0.9",
    "Connection": "keep-alive",
    "Content-Length": data.length,
    "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
    "Cookie": "connect.sid=s%3A2dTWSd1bfjY9aX2P42J6J4qzqEcyseoG.7V8fP85gjACREojrH9Bjtj2xF9F2YM%2BtYL3XyrBqd0I; _ga=GA1.2.1398122749.1594522616; _gid=GA1.2.956517977.1594522616; UM_distinctid=17340f43fdc31e-022e9f653e2209-3b634404-13c680-17340f43fdd722; CNZZDATA1254020586=1635525188-1594522618-https%253A%252F%252Fwww.baidu.com%252F%7C1594522618; node_club=s%3A5ac19da10ab0448f0fe3f7b2%24%24%24%24.c4TPrsdd%2B35kjylMrYe%2FaVl169ApEpHrl%2BaM0BUNUOI; _gat=1",
    "Host": "cnodejs.org",
    "Origin": "https://cnodejs.org",
    "Referer": "https://cnodejs.org/topic/5ee1ee83b703280f0bcb922a",
    "Sec-Fetch-Dest": "empty",
    "Sec-Fetch-Mode": "cors",
    "Sec-Fetch-Site": "same-origin",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36",
    "X-CSRF-Token": "J5pSyVpb-DPf18zuVRoeoRa3YtjiTrDmSbow",
    "X-Requested-With": "XMLHttpRequest"}
}

// 创建请求对象
var req = https.request(options, function(res) {
  var ret = ''
  res.on('data', function(data) {
    ret += data
  })
  res.on('end', function() {
    console.log(ret)
  })
})

req.on('error', function(err) {
  console.log('err', err)
})

5、events模块、事件触发器

如何创建一个事件触发器?

var EventEmitter = require('events')
var myEvent = new EventEmitter()

如何定义事件监听器?
myEvent.on('xxx', fn)
myEvent.once('xxx', fn)

如何触发事件?如何传递事件参数?
myEvent.emit('xxx', args)

6、fs模块,文件(夹)的增删改查

与文件夹相关的操作:创建、改名称、读、删

与文件相关的操作:写、读、删、改名称

//fs.stat
var fs = require('fs');

// 获取文件信息
fs.stat('package-lock.json', function(err, stats) {
  console.log(stats.isFile())
  console.log(stats.isDirectory())
})

//fs.mkdir
var fs = require('fs');

fs.mkdir('logs', function(err) {
  if (!err) {
    console.log('目录创建成功')
  }
})

//fs.writeFile,fs.appendFile
var fs = require('fs');

var filePath = 'logs/hello.txt'
var text = "写入文件的内容\n"

// 异步  覆写
fs.writeFile(filePath, text, function(err) {
  if (!err) {
    console.log('成功写入文件')
  }
})

// 异步  追加写入文件
fs.appendFile(filePath, text, function(err) {
  if (!err) {
    console.log('成功写入文件')
  }
})

//fs.readFile
var fs = require('fs');

var filePath = 'logs/hello.txt'

// 第一种写法
fs.readFile(filePath, function(err,data) {
  if(!err) {
    // 编码格式转化
    console.log(data.toString())
  }
})

fs.readFile(filePath, 'utf-8', function(err,data) {
  if(!err) {
    console.log(data)
  }
})

//fs.readdir
var fs = require('fs');

// 读取文件目录
fs.readdir(__dirname, function(err, files) {
  if (!err) {
    console.log(files)
  }
})
//fs.rename
var fs = require('fs');

var filePath = 'logs/hello.txt'
var newName = 'logs/greet.txt'

fs.rename(filePath, newName, function(err) {
  if(!err) {
    console.log('文件名称修改成功')
  }
})

// 不仅可以修改文件名
// 还可以修改文件夹的名字
var fs = require('fs');

// 遍历,删除文件
fs.readdirSync('logs').map(function(file) {
  // 注意,要使用同步方法
  fs.unlinkSync('logs/'+file, function(err) {
    console.log('文件遍历 删除成功')
  })
})


// 删除文件夹
// 注意,当文件夹不为空时,是无法删除的
fs.rmdirSync('logs', function(err) {
  if(!err) {
    console.log('目录删除成功')
  } else {
    console.log(err)
  }
})

7、stream模块

为什么需要使用流?
当文件较大时,避免一次性把数据读入到内存,所以使用流批量读取文件数据。

.pipe() 管道流的使用    
var fs = require('fs');

var inp = fs.createReadStream('package-lock.json')

var out = fs.createWriteStream('logs/a.txt');

//把inp文件写入out位置
inp.pipe(out);

8、path模块

path.join() //路径拼接
path.resolve() //将路径或路径片段的序列解析为绝对路径

Node.js原生Api 搭建服务器

1、什么是服务器?

提供服务的程序或设备,它的功能有接收并处理请求,处理并响应数据信息。

2、Node.js原生路由实现WebServer

原理,就是根据 req.url 来区分客户的请求路径,根据不同的访问路径响应不同内容。

nodejs代码实时编辑工具:nodemon

res.writeHead(200, {'Content-Type':'text/plain;charset=utf-8;'})
参见:HTTP媒体类型/MIME_Types

项目需求描述:
使用node.js原生代码,实现图片、HTML/CSS/JS文件的访问

var http = require('http')
var fs = require('fs')
var path = require('path')

var server = http.createServer(function(req, res) {
    var url = req.url
    // favicon.ico
    if (url != '/favicon.ico') {
        // url路径处理
        // 当用户直接访问 根路径 时
        url = url === '/' ? '/index.html' : url
        var filePath = path.join(__dirname, '/public' + url)
        // 判断是不是文件
        fs.stat(filePath, function(err, stats) {
            // 报错、或文件不存在时
            if (err || !stats) {
                res.writeHead(404, {'Content-Type':'text/plain;charset=utf-8;'})
                res.end('文件不存在 ')
            }
            // 如果是一个文件
            if (stats && stats.isFile()) {
                res.statusCode = 200
                res.setHeader('Content-text', 'text/plain;')
                // 读取文件,响应给客户端
                fs.createReadStream(filePath).pipe(res)
            }
        })
    }
})

// 端口监听
server.listen(8000, function() {
    console.log('server is running on 8000')
})

用Express 重构WebServer

Express安装:npm install express -S

实现静态资源服务器static

var express = require('express')
var app = express()

// 静态服务,在根目录创建 public 目录,把静态资源放进去
app.use(express.static('public'))

// 路由
app.get('/', (req, res) => {
  res.send('hello world')
})
// 端口监听
app.listen(8000, ()=>{
  console.log('server in running on 8000')
})
上一篇下一篇

猜你喜欢

热点阅读