流
-
为了提高性能,减少能耗【 cpu 】
管道流 【 连接 I/O 之间的一个管道】,这个管道我们称之为: pipe -
gulp就是一来了Node.js流的概念,它才能在grunt竞争中胜出
-
data Node.js中数据是分片【 chunk 】传输的
-
总结:
流这个概念 -
Node.js中数据传输是分片的流
压缩文件实例:
const zlib = require( 'zlib' ) // zlib是一个压缩包的内置模块
const fs = require( 'fs' ) // fs是文件系统
// const in = fs.createReadStream(文件路径)
// 通过fs文件系统将1.txt中的内容读出来 - 班长水杯中的水倒出来
const inp = fs.createReadStream('./dist/1.txt') // 创建可读的流
// 通过fs文件系统将 data 中的内容写进去const out = fs.createWriteStream('1.txt.gz') //创建可写的流
const gzlib = zlib.createGzlip() // 创建一个空的压缩包
inp
.pipe( gzlib )
.pipe( out )
爬虫
-
通过后端语言爬取网站中的额数据,然后通过特定模块进行数据清洗,最后将数据输出给前端。
-
不是那个网站都能爬取的
-
反爬虫
我们刚才数据清洗时,用的是 text() 这个获取的是a标签的内容解决: 给a标签的内容中放一张图片
回顾状态码:
1XX Informational(信息性状态码) 接受的请求正在处理
2XX Success(成功状态码) 请求正常处理完毕
3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
4XX Client Error(客户端错误状态码) 服务器无法处理请求
5XX Server Error(服务器错误状态码) 服务器处理请求出错
200 OK:请求已正常处理。
204 No Content:请求处理成功,但没有任何资源可以返回给客户端
206 Partial Content:是对资源某一部分的请求
304 Not Modified:资源已找到,但未符合条件请求
403 Forbidden:不允许访问那个资源
404 Not Found:服务器上没有请求的资源
500 Internal Server Error:貌似内部资源出故障了
实例
const http = require( 'http' )
http.get('http://nodejs.org/dist/index.json', (res) => {
const { statusCode } = res; // 获取状态码 1xx - 5xx
const contentType = res.headers['content-type']; // 文件类型 text/json/html/xml
let error;
// 错误报出,状态码不是200,报错,不是json类型报错
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
} else if (!/^application\/json/.test(contentType)) {
error = new Error('Invalid content-type.\n' +
`Expected application/json but received ${contentType}`);
}
if (error) {
console.error(error.message);
// consume response data to free up memory
res.resume(); // 继续请求
return;
}
res.setEncoding('utf8'); // 字符编码
// 核心 -- start
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; }); // 数据拼接
res.on('end', () => { // 数据获取结束
try {
const parsedData = JSON.parse(rawData);
console.log(parsedData);
} catch (e) {
console.error(e.message);
}
});
// 核心 -- end
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
获取后台名单实例
const http = require( 'http' )
const cheerio = require( 'cheerio' )
// http://jx.1000phone.net/teacher.php/Class/classDetail/param/rqiWlsefmajGmqJhXXWhl3ZiZGZp
const options = {
hostname: 'jx.1000phone.net',
port: 80,
path: '/teacher.php/Class/classDetail/param/rqiWlsefmajGmqJhXXWhl3ZiZGZp',
method: 'GET',
headers: {
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'Cache-Control':' no-cache',
Cookie: 'PHPSESSID=ST-22290-Uo8KnobsTgDO-TrQvhjA4TfoJI4-izm5ejd5j1npj2pjc7i3v4z',
Host: 'jx.1000phone.net',
Pragma: 'no-cache',
'Proxy-Connection': 'keep-alive',
Referer: 'http://jx.1000phone.net/teacher.php/Class/index',
'Upgrade-Insecure-Requests': 1,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': 0
}
};
const req = http.get( options, (res) => {
const { statusCode } = res; // 获取状态码 1xx - 5xx
const contentType = res.headers['content-type']; // 文件类型 text/json/html/xml
res.setEncoding('utf8'); // 字符编码
// 核心 -- start
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; }); // 数据拼接
res.on('end', () => { // 数据获取结束
try {
const $ = cheerio.load( rawData )
$('td.student a').each( function ( item ) {
console.log( $( this ).text() )
})
} catch (e) {
console.error(e.message);
}
});
// 核心 -- end
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
req.end()
后端中服务器类型有两种
1. web服务器【 静态服务器 】
-举例: wamp里面www目录
-目的是为了展示页面内容
-前端: nginx
2. 应用级服务器[ api服务器 ]
-后端接口
-tomcat
做什么?
使用Node.js原生代码实现静态服务器 【 必会 】
代码如下
const http = require( 'http' )
const port = 3000
const hostname = 'localhost' // 127.0.0.1
http.createServer((request,response) => {
response.writeHead( 200, {
'Content-Type': 'text/html;charset=utf8'
})
response.write('hello Node.js')
response.end()
}).listen(port,hostname,() => {
// 参数: 端口 域名 监听回调
console.log(`The Server is running at: http://${ hostname }:${ port }`)
})
Node.js中的模块化
模块化
- 为什么前端要使用模块化?
- 分析: html中引入多个js文件,使用script标签对
- Node.js都是js文件,思考: js文件如何引入其他类型文件
- 答案: 模块化
- 好处:
- 复用性高,一次定义,多次使用
前端模块化
AMD
- AMD的实现需要使用 require.js
CMD
- CMD的实现需要使用 sea.js 【 不更新 】
Common.js
Node.js使用了Common.js规范
1. 内置模块引用
Node.js中内置模块使用
1. 格式: var/let/const 变量名 = require(路径) 内置模块路径就是模块名称
2. 使用内置模块身上的方法
2.自定义模块引用
打造一个name的模块
打造步骤:
1. 创建模块 【 Function / Object / String
2. 导出模块
- module.exports = 模块名称 导出一个
- module.exports = {} // 导出多个
3. 导入模块
- var/let/const 变量名 = require( 相对【 网络 】路径 )
- var/let/const { 变量名 } = require( 相对路径 ) // 引入多个
// 1. 创建模块
const name = {
firstName: 'Gabriel',
lastName: 'Yan'
}
// 2. 导出模块
// module.exports = name
module.exports = {
name
}
3.第三方模块引用
request第三方模块
作用: 数据请求
使用:
1. 安装
npm/cnpm i/install request --dev-save/-D 开发环境安装
npm/cnpm i/install request --save/-S 生产环境安装
2. 导入
let/var/const 变量名 = require( 模块名称 )
3. 使用
思考: 我在Node.js文件中进行数据请求,存在跨域吗?
分析:
跨域 -》 同源策略 -》 浏览器
结果: 不存在
EcmaScript 模块化
- es5
- module.export / exports
- es6
- export default / export
总结:
- 1. AMD 和 CMD 都是通过关键字 define 来定义模块的,通过require来引入模块
- 2. es6模块化 【 前端里程碑 】
- export default 默认导出一个 , import xx from xxx
- export 批量导出,导出多个, import { xxx } from xxx
npm上传模块的步骤
1. 创建一个自定义模块 【 文件夹名称一定记住是唯一的,去npmjs.com查是否有 】
2. 创建package.json文件
3. 将npm源切换到npmjs上 【 nrm切换 】
- nrm安装: cnpm i nrm -g
- nrm ls 列出当前所有源
- nrm use 源名称 切换到某一个源
4. 注册npmjs.com账号 【 qq邮箱 】
5. 激活npmjs.com账号 【 重要/ 犯错高发点 】【 小弹框只出一次 】
6. 在当前目录下登录npm账号
- `$ npm adduser`
7. 填写用户名、密码、激活邮箱
8. 发布
- `$ npm publish`
前端开发环境
1 开发环境
2 生产环境
3 测试环境
- 测试代码运行情况
- 测试代码质量
- 测试代码风格
4 预上线环境
- beta版本 【 内测 】
5 上线环境
- 放在云服务器/服务器主机中的项目,可以供任何用户使用
npm脚本
概念:
npm 允许在package.json文件里面,使用scripts字段定义脚本命令。
例 {
// ...
"scripts": {
"build": "node build.js"
}}
原理
npm 脚本的原理非常简单。每当执行npm run,就会自动新建一个Shell(终端),在这个 Shell 里面执行指定的脚本命令。因此,只要是 Shell(一般是Bash)可以运行的命令,就可以写在 npm 脚本里面。比较特别的是,npm run新建的这个Shell,会将当前目录的node_modules/.bin子目录加入PATH变量,执行结束后,再将PATH变量恢复原样。这意味着,当前目录的node_modules/.bin子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径。比如,当前项目的依赖里面有 Mocha,只要直接写mocha test就可以了。