Node.js 模块
-
Node.js有三种模块:内置模块,自定义模块,第三方模块
###npm 使用入门
安装:无需安装
查看当前版本:
$ 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 }`)
})