美文网首页
NodeJS--01

NodeJS--01

作者: 幸之石 | 来源:发表于2020-07-13 19:24 被阅读0次

    前端框架的发展历史

    学习资源推荐

    • node.js官网:文档查询
    • npm官网:模块搜索
    • GitHub:大量的开源工具可供学习和使用
    • StackOverflow:学习中遇到的问题查询
    • SegmentFault:问题查询

    Node.js基础

    1、Node.js介绍

    编译型
    解释型

    为什么要学习node.js?

    • 辅助前端开发,搭建前端工程
    • 编写服务端业务、数据库开发

    什么是Node.js?

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

    • Chrome V8
    • 事件驱动
    • 非阻塞I/O

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

    什么是NPM?

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

    学习资源推荐

    • node.js官网:文档查询
    • npm官网:模块搜索
    • GitHub:大量的开源工具可供学习和使用
    • StackOverflow:学习中遇到的问题查询
    • SegmentFault:问题查询

    2、Node.js安装

    版本识别:

    12.3.2

    • LTS 稳定版本,建议安装
    • Current 最新版本
    • 主版本号.子版本号.修订版本号 v6.8.x
    • 子版本号为偶数的版本是稳定版本,为奇数的是非稳定版本
    • 建议安装LTS的偶数版本

    下载安装:

    • 在官网下载.msi安装包
    • 验证安装是否成功:在Git Bash中
    node -v
    npm -v
    

    nvm安装

    • Node Version Manager(Node版本管理工具)下载地址
    • 开发工作可能会在多个Node版本中测试,Node的版本也比较多,需要一款工具来管理
    • 基本命令
    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')
    })
    

    相关文章

      网友评论

          本文标题:NodeJS--01

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