获取状态码 1xx —— 5xx 必须记忆
- 1XX information(信息性状态码)接受的请求正在处理
- 2XX Success(成功状态码) 请求正常处理完毕
- 3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
- 4XX Client Error(客户端错误状态码) 服务器无法处理请求
- 5XX Server Error(服务器错误状态码) 服务器处理请求出错
使用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 }`)
})
流(stream)的基本概念
-
为了提高性能,减少能耗【 cpu 】
-
管道流 【 连接 I/O 之间的一个管道】,这个管道我们称之为:pipe
-
gulp就是一个来自Node.js流的概念,它才能在grunt竞争中胜出
-
Node.js中数据是分片(chunk)传输的
-
Node.js中数据传输是分片(chunk)的流
生成压缩包
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 )
http爬虫
爬虫
- 通过后端语言爬取网站中的数据,然后通过特定模块进行数据清洗,最后将数据输出给前端
- 不是哪个网站都能爬取的
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}`);
});
案例:
- http.get
- 数据清洗: 第三方插件【模块】 cheerio【不要写ES6】
反爬虫
解决: 给标签中的内容中放一张图片
Node.js中console模块 底层调用的是:process.stdout
后端中服务器类型有两种
-
web服务器【 静态服务器 】
- 举例:wamp里面www目录
- 目的是为了展示页面内容
- 前端: nginx
-
应用级服务器【api服务器】
- 后端接口
Node.js中的模块化【必会】
- 模块化:通过模块化可以把其他类型文件引入到js文件中
- 好处:复用性高,一次定义,多次使用
- 前端模块化
- AMD
- AMD的实现需要使用 require.js
- CMD
- CMD的实现需要使用 sea.js【不更新】
- Common.js
- Node.js使用了Common.js规范
- 内置模块引用
1. 格式: var / let / const 变量名 = require( 路径 ) 内置模块路径就是模块名称 2. 使用内置模块身上的方法 const fs = require( 'fs' ); fs.readFile('../dist/1.txt','utf8',( error,docs ) => { console.log( docs ); })
- 自定义模块引用
打造模块步骤: 1. 创建模块 【function / object / string】 const name = { firstName: 'Gabriel', lastName: 'Yan' } 2. 导出模块 - module.exports = 模块名称 module.exports = name 导出一个 - module.exports = {} 导出多个 3. 导入模块 - var/let/const 变量名 = require( 相对【 网络 】 路径) - var/let/const {变量名} = require (相对路径) 引入多个 const name = require( './name.js' ) const { name } = require( './name.js' ) const { age,xiaoyang } = require( './age.js' )
- 第三方模块引用
- 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文件中进行数据请求不存在跨域 const request = require( 'request' ) request('https://m.lagou.com/listmore.json',( error,response,body ) => { // 参数说明: error 错误信息 response 响应结果 body 获取的数据 console.log( body ) })
- Node.js使用了Common.js规范
- AMD
- EcmaScript 模块化
- es5
- module.export / exports
- es6
- export default / export
- es5
- 总结:
-
- AMD 和CMD 都是关键字 define来定义模块的,通过require来引入模块
-
- es6模块化【 前端里程碑 】
- export default 默认导出一个 export xx from xxx
- export 批量导出,导出多个 import {xxx} from xxx
-
后端中不存在跨域 跨域只存在于前端
- npm【 了解 】
- npm包上传npmjs.com这个网站
- 步骤:
- 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
- 前端环境
- 开发环境
- 生产环境
- 二阶段项目
- 测试环境
- 测试代码运行情况
- 测试代码质量
- 测试代码风格
- 预上线环境
- beta版本【内测】
- 上线环境
- 放在云服务器 / 服务器主机中的项目,可以供任何用户使用
npm脚本
-
什么是npm脚本
- Node开发离不开npm,而脚本功能是npm最强大、最常用的功能之一。
- npm 允许在package.json文件里面,使用scripts字段定义脚本命令。
{ // ... "scripts": { "build": "node build.js" }}
- 命令行下使用npm run命令,就可以执行这段脚本
$ npm run build 等同于执行 $ node build.js
- 优点:
- 项目的相关脚本,可以集中在一个地方
- 外接口。用户不同项目的脚本命令,只要功能相同,就可以有同样的,对需要知道怎么测试你的项目,只要运行npm run test即可。
- 可以利用npm提供的很多辅助功能
- 查看当前项目的所有npm脚本命令,可以使用不带任何参数的npm run命令
```python
$ npm run
```
- 原理
- npm 脚本的原理非常简单。每当执行npm run,就会自动新建一个 Shell(终端),在这个 Shell 里面执行指定的脚本命令。因此,只要是 Shell(一般是 Bash)可以运行的命令,就可以写在 npm 脚本里面。
- 比较特别的是,npm run新建的这个 Shell,会将当前目录的node_modules/.bin子目录加入PATH变量,执行结束后,再将PATH变量恢复原样。
- 这意味着,当前目录的node_modules/.bin子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径。比如,当前项目的依赖里面有 Mocha,只要直接写mocha test就可以了。
-
"test": "mocha test"退出码
- 执行顺序
- 如果 npm脚本里面需要执行多个任务,那么需要明确它们的执行顺序。
如果是并行执行(即同时的平行执行),可以使用&符号。
- 如果 npm脚本里面需要执行多个任务,那么需要明确它们的执行顺序。
-
$ npm run script1.js & npm run script2.js
- 如果是继发执行(即只有前一个任务成功,才执行下一个任务),可以使用&&符号。
-
$ npm run script1.js && npm run script2.js
-
默认值
- 一般来说,npm 脚本由用户提供。但是,npm 对两个脚本提供了默认值。也就是说,这两个脚本不用定义,就可以直接使用。
"start": "node server.js", "install": "node-gyp rebuild", "build": "node build.js"
- 上面代码中,npm run start的默认值是node server.js,前提是项目根目录下有server.js这个脚本;npm run install的默认值是node-gyp rebuild,前提是项目根目录下有对应的文件。
-
钩子
- npm脚本有pre和post两个钩子。举例来说,build脚本命令的钩子就是prebuild和postbuild。
"prebuild": "echo I run before the build script", "build": "cross-env NODE_ENV=production webpack", "postbuild": "echo I run after the build script"
- 用户执行npm run build的时候,会自动按照下面的顺序执行。
npm run prebuild && npm run build && npm run postbuild
- npm默认提供下面这些钩子
prepublish,postpublish preinstall,postinstall preuninstall,postuninstall preversion,postversion pretest,posttest prestop,poststop prestart,poststart prerestart,postrestart
-
变量
- npm 脚本有一个非常强大的功能,就是可以使用 npm 的内部变量。
首先,通过npm_package_前缀,npm 脚本可以拿到package.json里面的字段。比如,下面是一个package.json。
{ "name": "foo", "version": "1.2.5", "scripts": { "view": "node view.js" }} // view.js console.log(process.env.npm_package_name); // foo console.log(process.env.npm_package_version); // 1.2.5
- 注意,package.json里面的config对象,可以被环境变量覆盖。
{ "name" : "foo", "config" : { "port" : "8080" }, "scripts" : { "start" : "node server.js" }}
- 上面代码中,npm_package_config_port变量返回的是8080。这个值可以用下面的方法覆盖。
$ npm config set foo:port 80
- 最后,env命令可以列出所有环境变量。
"env": "env"
- npm 脚本有一个非常强大的功能,就是可以使用 npm 的内部变量。