Node.js模块

Node.js 模块

  • Node.js有三种模块:内置模块,自定义模块,第三方模块
    ###npm 使用入门

    官网:https://www.npmjs.com/

    安装:无需安装

    查看当前版本:

     $ npm -v
    

    更新:

     $ npm install npm@latest -g
    
    

    初始化工程

     $ npm init
    
     $ npm init --yes 默认配置
    

    安装包

    使用npm install会读取package.json文件来安装模块。安装的模块分为两类
    dependencies和devDependencies,分别对应生产环境需要的安装包和开发环境需要的安装包。

     $ npm install
    
     $ npm install <package_name> 
    
     $ npm install <package_name> --save
    
     $ npm install <package_name> --save-dev
    

    更新模块

     $ npm update
    

    卸载模块

     $ npm uninstall <package_name>
    
     $ npm uninstall --save lodash
    

内置模块

  • 引用

require方法用于加载模块。

 	var example = require('./example.js');
	console.log(example.x); // 5
	console.log(example.addX(1)); // 6
  • 内置模块
	const process = require('process')
	const path = require('path')
	console.log(process.version)
	console.log(path.resolve('../'))

常用的内置模块

node 常用内置api

(1) URL 网址解析

解析URL相关网址信息
​ url.parse(urlString[, parseQueryString[, slashesDenoteHost]])
​ url.format(urlObject)
​ url.resolve(from, to)

(2) QueryString 参数处理

​ querystring.escape(str) 使传入的字符串进行编码*(对中文进行编码)
querystring.unescape(str) 将含有%的字符串进行解码(将中文进行解码)
querystring.parse(str[, sep[, eq[, options]]]) 将字符串转换为对象
​ querystring.stringify(obj[, sep[, eq[, options]]]) 将对象转换为字符串*

(3) HTTP 模块概要

​ http.createServer([options][, requestListener])*

​ http.get(options[, callback])*

​ http模块

​ 业务: 从nowapi中找一个免费接口,进行数据请求 (www.nowapi.com)

此处选择的接口是天气预报的接口:
const http = require('http');//使用HTTP模块
http.get('http://api.k780.com/?app=weather.wtype&appkey=42553&sign=ff6f5ddc291caf89a8ddf988790b4186&format=json', (res) => {
    const { statusCode } = res; //获取请求状态码
    const contentType = res.headers['content-type']; //获取请求的数据类型

    let error;
    if (statusCode !== 200) { //如果状态码不是200,输出报错信息
        error = new Error('请求失败\n' +
            `状态码: ${statusCode}`);
    } else if (!/^application\/json/.test(contentType)) {
        error = new Error('无效的 content-type.\n' +
            `期望的是 application/json 但接收到的是 ${contentType}`);
    }
    if (error) { //如果报错了,将报错信息存入日志
        console.error(error.message);
        // 消费响应数据来释放内存。
        res.resume();
        return;
    }
    res.setEncoding('utf8'); //字符编码
    let rawData = '';
    res.on('data', (chunk) => { rawData += chunk; }); //通过data事件拼接数据流
    res.on('end', () => { //获取数据结束
        try { //高级程序语法  捕捉错误信息
            const parsedData = JSON.parse(rawData);
            console.log(parsedData);
        } catch (e) {
            console.error(e.message);
        }
    });
}).on('error', (e) => {
    console.error(`出现错误: ${e.message}`);
});
输出之后的结果:
   { '1': { wtId: '1', wtNm: '晴', icon: '00', oicon: '0' },
     '2': { wtId: '2', wtNm: '多云', icon: '01', oicon: '1' },
     '3': { wtId: '3', wtNm: '阴', icon: '02', oicon: '2' },
     '4': { wtId: '4', wtNm: '阵雨', icon: '03', oicon: '3' },
     '5': { wtId: '5', wtNm: '雷阵雨', icon: '04', oicon: '4' },
     '6': { wtId: '6', wtNm: '雷阵雨有冰雹', icon: '05', oicon: '5' },
     '7': { wtId: '7', wtNm: '雨夹雪', icon: '06', oicon: '6' },
     '8': { wtId: '8', wtNm: '小雨', icon: '07', oicon: '7' },
     '9': { wtId: '9', wtNm: '中雨', icon: '08', oicon: '8' },
     '10': { wtId: '10', wtNm: '大雨', icon: '09', oicon: '9' },
     '11': { wtId: '11', wtNm: '暴雨', icon: '10', oicon: '10' },
     '12': { wtId: '12', wtNm: '大暴雨', icon: '11', oicon: '11' },
     '13': { wtId: '13', wtNm: '特大暴雨', icon: '12', oicon: '12' },
     '14': { wtId: '14', wtNm: '阵雪', icon: '13', oicon: '13' },
     '15': { wtId: '15', wtNm: '小雪', icon: '14', oicon: '14' },
     '16': { wtId: '16', wtNm: '中雪', icon: '15', oicon: '15' },
     '17': { wtId: '17', wtNm: '大雪', icon: '16', oicon: '16' },
     '18': { wtId: '18', wtNm: '暴雪', icon: '17', oicon: '17' },
     '19': { wtId: '19', wtNm: '雾', icon: '18', oicon: '18' },
     '20': { wtId: '20', wtNm: '冻雨', icon: '19', oicon: '19' },
     '21': { wtId: '21', wtNm: '沙尘暴', icon: '20', oicon: '20' },
     '22': { wtId: '22', wtNm: '小到中雨', icon: '21', oicon: '21' },
     '23': { wtId: '23', wtNm: '中到大雨', icon: '22', oicon: '22' },
     '24': { wtId: '24', wtNm: '大到暴雨', icon: '23', oicon: '23' },
     '25': { wtId: '25', wtNm: '暴雨到大暴雨', icon: '24', oicon: '24' },
     '26': { wtId: '26', wtNm: '大暴雨到特大暴雨', icon: '25', oicon: '25' },
     '27': { wtId: '27', wtNm: '小雪到中雪', icon: '26', oicon: '26' },
     '28': { wtId: '28', wtNm: '中雪到大雪', icon: '27', oicon: '27' },
     '29': { wtId: '29', wtNm: '大雪到暴雪', icon: '28', oicon: '28' },
     '30': { wtId: '30', wtNm: '浮尘', icon: '29', oicon: '29' },
     '31': { wtId: '31', wtNm: '扬沙', icon: '30', oicon: '30' },
     '32': { wtId: '32', wtNm: '强沙尘暴', icon: '31', oicon: '31' },
     '33': { wtId: '33', wtNm: '霾', icon: '53', oicon: '53' },
     '34': { wtId: '34', wtNm: '浓雾', icon: '32', oicon: '18' },
     '35': { wtId: '35', wtNm: '强浓雾', icon: '49', oicon: '18' },
     '36': { wtId: '36', wtNm: '中度霾', icon: '54', oicon: '53' },
     '37': { wtId: '37', wtNm: '重度霾', icon: '55', oicon: '53' },
     '38': { wtId: '38', wtNm: '严重霾', icon: '56', oicon: '53' },
     '39': { wtId: '39', wtNm: '大雾', icon: '57', oicon: '18' },
     '40': { wtId: '40', wtNm: '特强浓雾', icon: '58', oicon: '18' },
     '41': { wtId: '41', wtNm: '雨', icon: '301', oicon: '7' },
     '42': { wtId: '42', wtNm: '雪', icon: '302', oicon: '14' },
     '99': { wtId: '99', wtNm: '无', icon: '99', oicon: '99' } } }
  • http.爬虫

​ * 去某一个网站爬取一段数据 -> 数据清洗 -> 后端服务器 -> 发送前端 -> 渲染数据

​ * 不是所有网站都可以爬取

​ * 爬虫: 后端渲染的网站才能爬取数据

  • 爬虫是要基于后端的,所以在此使用Node.js创建一个静态服务器
  • 后端服务器有两种类型

​ * web服务器 【 静态服务器 】

​ * api服务器 【 暴露接口 】

  /* 请求头部报文
    1. general 请求基本信息
    2. response Headers  响应头
    3. request Headers  请求头
    4. 携带参数
      - query string paramters   get请求
      - form data  post 请求

*/

const http = require('http')
const host = 'localhost'
const port = 8000


http.createServer((request, response) => {

    // response.writeHead( 状态码,请求头 )
    response.writeHead(200, {
        'Content-type': 'text/html;charset=utf8'
    })

    response.write('<h3> 这里使用Node创建的一个静态服务器 </h3>') // 往前端发送信息

    response.end() // 告诉前端信息已经结束了

}).listen(port, host, () => {
    console.log(`The server is running at: http://${ host }:${ port }`)
})

以下是正式爬取数据:

const http = require( 'http' )
const host = 'localhost'  
const port = 8000 


http.createServer(( request,response ) => {

  // response.writeHead( 状态码,请求头 )
  response.writeHead( 200, {
    'Content-type': 'text/html;charset=utf8'
  })

    const http = require( 'http' )
    // 引入第三方类库
    const cheerio = require( 'cheerio' )

    const options = {
      hostname: '要爬取网页的网址',
      port: 80,//端口号
      path: '网址?号后面的部分',
      method: 'GET',//请求方式
      headers: {
        Accept: '控制台可查看',
        'Accept-Encoding': '控制台打开可查看',
        'Accept-Language': '控制台打开可查看',
        'Cache-Control':'控制台打开可查看',
        Cookie: '控制台打开可查看',
        Host: '控制台打开可查看',
        Pragma: '控制台打开可查看',
        'Proxy-Connection': '控制台打开可查看',
        Referer: '控制台打开可查看',
        'Upgrade-Insecure-Requests': 1,
        'User-Agent':'控制台打开可查看',
        'Content-Type': '控制台打开可查看',
        'Content-Length': 0
      }
    }


    http.get( options, (res) => {
      const { statusCode } = res; // 获取请求状态码
      const contentType = res.headers['content-type']; //获取请求类型数据类型
      res.setEncoding('utf8'); // 字符编码
      let rawData = '';
      res.on('data', (chunk) => { rawData += chunk; }); // 通过data事件拼接数据流
      res.on('end', () => { // 获取数据结束了 
        try { // 高级编程语法         捕获错误信息
          const $ = cheerio.load( rawData )
          $('td.student a').each(function (index,item) {
            response.write(`<h3> ${ $( this ).text() }  </h3>`) // 往前端发送信息
          })
          response.end() // 告诉前端信息已经结束了
        } catch (e) {
          console.error(e.message);
        }
      });
    }).on('error', (e) => {
      console.error(`Got error: ${e.message}`);
    });

  
  
}).listen( port,host,() => {
  console.log( `The server is running at: http://${ host }:${ port }` )
})
(4) 事件 events 模块
  • Node.js中event模块
  • ​ Node.js中 事件的发布 + 事件的订阅 表示一个任务的执行
const Events = require('events')
const fs = require( 'fs' )
const http = require( 'http' )
const host = 'localhost'
const port = 3000


class myEvent extends Events{} //类的继承


const myevent = new myEvent() // 实例化类得到一个实例


// console.log( myevent )


//事件的发布

// myevent.on(事件名称,事件的回调函数)
myevent.on('aa',function () {
  // 书写任务
  // 任务: 将yyb.txt中的内容发送前台
  http.createServer( ( req,res ) => {
    res.writeHead( 200,{
      'Content-Type': 'text/html;charset=utf8'
    })
    // 1
    fs.readFile('./yyb.txt','utf8',( error,docs ) => { // error作为第一个参数的回调函数,我们叫做错误优先的回调函数
      res.write(`<h3> ${ docs } </h3>`)
      res.end()
    })
    // 2
    // why? 错误?
    // res.end()

  }).listen( port,host,() => {
    console.log( `服务器运行在: http://${ host }:${ port }` )
  })
})

// 事件的订阅


// myevent.emit(事件名称)
myevent.emit( 'aa' )
(5) 文件fs模块

​ 打印目录树

(6) Stream 流模块

  • stream流,流指的是数据流,指的是数据是分片传输

  • ​ 数据可以实现非阻塞

​ * 例:gulp 【 流式操作 】

  • 案例: 打包压缩包

  • ​ 流程:

  • ​ 1. 读取文件

  • ​ 2. 创建压缩包

  • ​ 3. 将读取的数据流写入压缩包

  • ​ 4. 输出压缩包

const fs = require('fs'); //读取文件

const zlib = require('zlib'); //创建压缩包

const inp = fs.createReadStream('./jxq.txt'); //读出数据

const gzip = zlib.createGzip() //创建压缩包

const outp = fs.createWriteStream('./jxq.txt.gz'); //gz  表示的就是压缩包

jnp
    .pipe(gzip)
    .pipe(outp);

自定义模块

文件名:name.js

// 自定义模块

//1.创建模块
const obj = {
    id: 2,
    name: '你好,世界'
}
const str = '12000'

//2.导出模块

// module.exports = obj; //只能导出一个

module.exports = { //批量导出
    obj,
    str

}
文件名:name2.js

//模块的导入

//;//在创建模块的文件中,如果导出的模块使用的是 module.exports = obj;  那对应的模块导入代码就是const obj = require('./name.js')

const { obj, str } = require('./name.js');
console.log(obj.name, str);

第三方模块

一般都是从npmjs.com这个网站拉取

​ 使用流程:

​ 1. 安装

​ 先创建package.json 文件

​ 在指令中输出:npm/cnpm i request -S/-D

​ -S --save 生产环境

​ -D --save-dev dev development的简写 开发环境

​ 注:此处 npm/cnpm i request -S 和 npm/cnpm i request -D都要安装,且S和D是大写

​ 2. 使用

​ request这个模块是做数据请求

​ 3. Node中数据请求存在跨域吗?

​ - 不存在

const three = require('request');

three('https://m.lagou.com/listmore.json', (a, b, c) => {
    console.log('a', a); //error
    console.log('b', b); //response 返回所以结果
    console.log('c', c); //body 数据  string
});

express

  • 后端

​ *api服务器

​ Node.js中api服务器的创建,我们使用一个第三方库 express

  • ​ 后端解决跨域问题:

​ *设置请求头

​ * 使用中间件

const express = require( 'express' )

const app = express() // 得到一个app对象

const port = 3000 

const host = 'localhost'

const cors = require( 'cors' )


// 创建接口

app.use(cors({
  "origin": "*",
  "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
  "preflightContinue": false,
  "optionsSuccessStatus": 200
}))

app.get( '/user', ( req,res,next ) => { // 回调函数我们称之为: 中间件   具有特定功能的一个函数
  res.json({
    id: 1,
    name: '前端学习',
    class: '666'
  })

})
app.get( '/demo', ( req,res,next ) => { // 回调函数我们称之为: 中间件   具有特定功能的一个函数
  res.json({
    id: 2,
    name: '前端学习2',
    class: '666'
  })

})


// 创建api服务器,并监听这个服务器
app.listen( port,host,() => {
  console.log( `The server is running at : http://${ host }:${ port }` )
})
反向代理

反向代理的基本原理

  • ​ 我们的后端帮助我们请求数据 , 在将数据发送给我们自己前端

​ 任务:

  • ​ 后端请求数据
  • ​ 将数据发送给前端 api服务器 express
const request = require( 'request' )

const express = require( 'express' )

const host = 'localhost'

const port = 3000

const app = express() 

const url = 'https://m.lagou.com/listmore.json'

//创建接口

app.get('/position', ( req,res,next ) => {
  res.setHeader('Access-Control-Allow-Origin', '*'); // 设置请求头跨域
  // 数据请求
  request( url, ( error,response,body ) => {
    res.json( JSON.parse( body ) )
  })

})


app.listen( port,host,  () => {
  console.log( `The server is running at: http://${ host }:${ port }`)
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值