NodeJs 学习
node.js 介绍
node.js 是什么?
- node.js 是一个开发平台,就像Java开发平台、.Net开发平台、PHP开发平台、Apple开发平台一样。
- 何为开发平台?有对应的编程语言、有语言运行时、有能实现特定功能的API(SDK:Software Development Kit)
- nodejs平台使用的编程语言是 JavaScript 语言。
- 不支持 window、document、bom 对象。
node.js平台是基于 Chrome V8 JavaScript 引擎构建。
基于 node.js 可以开发控制台程序(命令行程序、CLI程序)、桌面应用程序(GUI)(借助 node-webkit、electron 等框架实现)、Web 应用程序(网站)。
PHP开发技术栈: LAMP - Linux Apache MySQL PHP
node.js 全栈开发技术栈: MEAN - MongoDB Express Angular Node.js
node.js 有哪些特点?
- 事件驱动(当事件被触发时,执行传递过去的回调函数)
- 非阻塞 I/O 模型(当执行I/O操作时,不会阻塞线程)
- 单线程
- 拥有世界最大的开源库生态系统 —— npm。
node.js 网站
学习目标
- 了解服务器开发过程
- 会使用 node.js 开发基本的 http 服务程序(Web应用程序)
Node.js可以用来做什么?
- 具有复杂逻辑的动态网站
- WebSocket服务器
- 命令行工具
- 带有图形界面的本地应用程序
- ···
终端基本使用
打开应用
- notepad 打开记事本
- mspaint 打开画图
- calc 打开计算机
- write 打开写字板
- sysdm.cpl 打开环境变量设置窗口
常用命令
- md 创建目录
- rmdir(rd) 删除目录,目录内没有文档
- echo on a.txt 创建空文件
- del 删除文件
- rm 文件名 删除文件
Node.js开发环境准备
普通安装方式官方网站
多版本安装方式
- 卸载已有的Node.js
- 下载nvm
- 在C盘创建目录dev
- 在dev目中中创建两个子目录nvm和nodejs
- 并且把nvm包解压进去nvm目录中
- 在install.cmd文件上面右键选择【以管理员身份运行】
- 打开的cmd窗口直接回车会生成一个settings.txt文件,修改文件中配置信息
- 配置nvm和Node.js环境变量
NVM_HOME:C:\dev\nvm
NVM_SYMLINK:C:\dev\nodejs
- 把配置好的两个环境变量加到Path中
nvm常用的命令
- nvm list 查看当前安装的Node.js所有版本
- nvm install 版本号 安装指定版本的Node.js
- nvm uninstall 版本号 卸载指定版本的Node.js
- nvm use 版本号 选择指定版本的Node.js
Node.js之HelloWorld
- 命令行方式REPL
- 运行文件方式
- 全局对象概览
Node.js 开发 Web 应用程序 和 PHP、Java、ASP.Net等传统模式开发Web应用程序区别
- 有 Web 容器
- 没有 Web 容器
在 node.js 上编写程序
REPL 介绍
- REPL 全称: Read-Eval-Print-Loop(交互式解释器)
- R 读取 - 读取用户输入,解析输入了 Javascript 数据结构并存储在内存中。
- E 执行 - 执行输入的数据结构
- P 打印 - 输出结果
- L 循环 - 循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出。
- 在 REPL 中编写程序 (类似于浏览器开发人员工具中的控制台功能)
- 直接在控制台输入 node 命令进入 REPL 环境
- 按两次 Control + C 退出 REPL 界面 或者 输入 .exit 退出 REPL 界面
- 按住 control 键不要放开, 然后按两下 c 键
创建 JavaScript 文件编写程序
JavaScript 文件名命名规则
- 不要用中文
- 不要包含空格
- 不要出现 node 关键字,比如:node.js
- 建议以 ‘-’ 分割单词
案例 1:编写一个简单的函数, 实现数字相加
1 |
|
案例 2:文件读写案例
NodeJs笔记
浏览器渲染过程
1、HTML解析器会将HTML标记 生成DOM树
2、将CSS标记生成CSS规则树
3、将DOM与CSS规则树合并成一个render树
4、根据render树来布局,计算每个节点的几何信息
5、将各个节点绘制到浏览器上
浏览器访问过程
输入URL访问
浏览器构建请求行
查找强缓存
DNS解析
客户端与服务端进行TCP三次握手连接
在TCP连接的基础上发送HTTP请求
服务端处理请求并返回HTTP报文
浏览器解析渲染页面
连接结束,四次挥手断开连接
回流重绘
回流
当元素尺寸,位置或者内容,或者触发伪类等操作使得样式发生变化导致浏览器 DOM 发生变化的时候会发生浏览器回流,回流的代价很高,有时候一个 DOM 回流可能会导致多个节点发生回流
重绘
当浏览器样式发生改变但并不影响 DOM 布局的时候,会发生浏览器重绘,例如 color , background 等改变就会触发浏览器的重绘。
documentFragment是什么
documentFragment是一个保存多个element的容器对象(保存在内存)当更新其中的一个或者多个element时,页面不会更新。只有当documentFragment容器中保存的所有element更新后再将其插入到页面中才能更新页面。
列如将ul里面的li取出放到documentFragment,更新完毕后再将其插入到ul,一共有以下四步骤:
创建documentFragment对象fragment
取出ul中的所有子节点并保存到fragment
更新fragment中的所有节点(li的内容)
将fragment插入到ul
事件轮询?(EventLoop)
一个用来等待和发送消息和事件的程序结构。
1、所有任务都在主线程上执行,形成一个执行栈。
2、主线程发现有异步任务,如果是微任务就把他放到微任务的消息队列里,如果是宏任务就把他
放到宏任务的消息队列里。
3、执行栈所有同步任务执行完毕。
4、执行微任务队列,之后再执行宏任务队列。
5、轮询第4步。
引入读写文件的模块
1 |
|
写文件
fs.writeFile(参数1,参数2,参数3,参数4) //替换
参数1:要写入的文件路径,必填。
参数2:要写入的数据,必填。可以是字符串类型或者buffer类型
参数3:写入文件时的选项,比如:文件编码,选填。默认是utf8
参数4:文件写入完毕后的回调函数,必填。fs.appendFile() //追加
1 |
|
读文件
fs.readFile(参数1,参数2,参数3) //读取
参数1:要读取的文件路径,必填。
参数2:读取文件时的选项,比如:文件编码。选填。
参数3:文件读取完毕后的回调函数,必填。
1 |
|
__dirname 和 __filename
1 |
|
创建文件
fs.mkdir(参数1,参数2)
参数1:创建文件的路径,必填
参数2:回调函数,必填
1 |
|
try
异步操作无法通过 try-catch 来捕获异常,要通过判断 error 来判断是否出错。
1 |
|
加载http模块
1 |
|
创建http服务
1 |
|
监听’requers’事件
server.on()
参数1:’requers’
参数2:回调函数,必填
- req: 请求对象 包含了请求报文解析后的数据 通过它可以获取前端提交的数据
- res: 响应对象 通过它给前端发送响应或者设置响应头等操作 …
1 |
|
启动服务,开始监听
1 |
|
path
1 |
|
mime
// 初始化: npm init -y
// 安装: npm i mime
1 |
|
path.join()
path.join() 方法使用平台特定的分隔符把全部给定的 path 片段连接到一起,并规范化生成的路径。
通过设置 http 响应报文头实现弹框下载功能
1.设置 Content-Type: application/octet-stream || application/force-download
2.设置 Content-Disposition: attachment; filename=demo.txt
1 |
|
request对象 和 response对象
request 对象
1.request 对象类型 <http.IncomingMessage>, 继承自stream.Readable
2.request 对象常用成员
- request.headers
- request.rawHeaders
- request.httpVersion
- request.method
- request.url
response 对象
1.response 对象类型 <http.ServerResponse>
response.writeHead
response.write
response.end
response.setHeader
response.statusCode
response.statusMessage
模板
1 |
|
为什么会有 Buffer 类型?
- Buffer 使用来临时存储一些数据(二进制数据)
- 当我们要把一大块数据从一个地方传输到另外一个地方的时候可以通过 Buffer 对象进行传输
- 通过 Buffer 每次可以传输小部分数据,直到所有数据都传输完毕。
res.end和res.send的区别?
1、end支持的数据类型:Buffer对象, 字符串
2、send支持的数据类型:Buffer对象,字符串,对象,布尔,数组
1、end默认不会自动匹配一些响应头给浏览器 需要手动设置 res.setHeader(…)
2、send会自动匹配一些响应头给浏览器 解决乱码等问题
加载 Express
1 |
|
调用 express() 得到一个app实例
1 |
|
路由
app.get :
1、限制请求路径 需要完全匹配
2、限制请求方式 需要完全匹配
app.use:
1、不限制请求方式 任何请求方式都可以 => 使用中间件
2、限制请求路径 需要第一段完全匹配即可(pathName)
app.all:
1、不限制请求方式 任何请求方式都可以
2、限制请求路径 需要完全匹配
1 |
|
监听端口号,启动 Web 服务
1 |
|
express中requst对象新增的成员
- req.body: 需要使用中间件body-parsing解析提交的请求体
- req.params 获取params方式传递的参数 / 后面的参数
- req.query 获取query方式传递的参数 ? 后面的查询字符串 => { age: ‘18’ }
- req.cookies 获取前端提交的cookies => 需要配合cookie-parser中间件使用
- req.path 请求路径 域名后面?前面的内容
express重定向
1 |
|
express 中 res对象新增的成员
res.send:
res.redirect: 重定向
res.sendFile : 读取文件并响应
res.set: 设置响应头
res.type: 获取mimeType类型
1 |
|
静态资源托管
1 |
|
默认第一个参数为 / 表示的是根路径
中间件是有执行顺序的 从上往下依次执行
如果第一个托管的目录中查找不到指定的资源 就继续往下匹配
ejs模板
1 |
|
中间件
我们希望在不修改原有代码的情况下 去新增一个打印日志的功能 => 中间件
中间件一定是一个函数
1 |
|