一、node基础
1.介绍
- 作用:用来实现后台管理程序
- 目的:数据服务,文件服务,web服务
- 类似:php,.net,java(jsp) …
- 由 c++ 编写
2.优势:
- 性能高,方便,入门难
- 能用的上的学习资料少,对程序员的要求高,大公司都在用(BAT)
3.环境:nodejs + web服务器 + 数据库
- 官网:https://nodejs.org/zh-cn/
- 测试环境: 命令行(运行->cmd)->node -v
4.劣势:
- 服务器提供的相对较少: http://nodejs.cn/
5.版本介绍:
- Vx(主).x(子).x(修正)
- 主:1/3的API发生巨变,使用方式变化了
- 子:API没有删减,使用方式没变化,内部实现发生了变化
- 修正版:什么都没变,处理一下bug
- V6.8.x 稳定
- V6.9.x 非稳定版
- Vx.x.x-beta 测试
- vx.x.x-rc 测试稳定
- vx.x.x-alpha 测试稳定
6.运行:
- DOS命令(小黑框):
- win+r -> cmd回车 -> cd 目录 -> node 文件名.js | node 文件名
- vscode -> 终端
- 当前目录 -> 右键 -> git bash -> node 文件名
- linux/centos(git):
- 终端 -> cd 目录 -> node 文件名.js | node 文件名
7.node命令行:
- DOS -> node 回车 -> 编写+运行
- 一般只是测试API的可用度
8. 注意:
- DOM/BOM 不可用
- ECMA 可用
二、node的模块化规范:commonJS
- commonJS 是 nodejs 默认模块管理方式,不支持es6的模块化管理方式,但支持所有es6+语法
1. 模块化的目的
- 是主要为了JS在后端的表现制定
- commonJS 是个规范 nodejs / webpack 是一个实现
- ECMA 是个规范 js 实现了
2. 模块化方式
- 服务器端JS:相同的代码需要多次执行 | CPU和内存资源是瓶颈 | 加载时从磁盘中加载
- node模块: http / fs / querystring / url
- 模块化方式:require(‘模块名’) 系统模块
- 浏览器端js:代码需要从一个服务器端分发到多个客户端执行 | 带宽是瓶颈 | 通过网络加载
- 模块化方式:require、module、exports
- seajs.js / require.js CMD/AMD
3. commonJS模块化方式
-
require 引入模块、输入
- require(‘模块名’)
- 不指定路径:先找系统模块 -> 再从项目环境找node_modules | bower_components (依赖模块)-> not found
- 指定路径:指定路径 -> not found
- require输入的是一个对象
- require(‘模块名’)
-
exports 导出,批量输出,都是属性
- exports.自定义属性 = 值
-
module 默认输出,只能输出一次,require输入的是任意接收
- module.exports = { 自定义属性:值 }
三、node内置模块
http模块
- nodejs搭建web服务器
-
引入模块:const http = require(‘http’);
-
创建服务:
- server/app = http.createServer(函数(req,res)); // 返回http对象
- require:请求:浏览器 -> 服务器
- req.url 地址,提取地址栏数据
- req.on(‘data|end’); 提取非地址栏数据,所有的http[s]都会触发end事件
- response:响应:服务器 -> 浏览器
- 响应头设置:res.writeHead(200,{‘Content-Type’:‘text/html;charset=utf-8’});
- res.write(字符/数据)
- res.end(); 结束响应
- require:请求:浏览器 -> 服务器
- 监听:
- server.listen(端口,[地址],[回调])
- 端口:1-65535,1024以下系统占用,80
- 地址:虚拟localhost 真实域名xx.duapp.com
- 回调:监听成功,回调一次
- 小提示:
- 服务器代码更新后,需要重启服务器
- 自动重启工具: supervisor | nodemon 命令行工具
- npm install supervisor -g | npm install nodemon -g
- 接口测试工具
- postman
- insominia
文件服务模块 - file system 模块
-
引入模块:const fs = require(‘fs’);
-
功能:读,写,删,改
-
读:
1.fs.readFile(‘路径’,[配置],回调(err,data))
- 有回调,是异步
- err:错误,null或者undefined,表示没有错误
- ps:错误优先机制,回调函数的第一个参数为错误信息
- data:二进制buffer流
- ps:想获得原字符串内容就要加toString()方法;
- err:错误,null或者undefined,表示没有错误
- 有回调,是异步
- let data = fs.readFileSync(‘路径’,[配置])
- 同步,免去回调地狱,尽量用这种写法,但是比较占用时间
- 结论:异步读取文件由操作系统在后台读取,不会阻碍下面代码执行。同步读取阻碍下面代码执行。
-
写:
- fs.writeFile(‘路径’,‘内容’,回调(err))
- 有回调,是异步
- err:错误,null或者undefined,表示没有错误
- 有回调,是异步
- let data = fs.writeFileSync(‘路径’,‘内容’)
同步,免去回调地狱,尽量用这种写法,但是比较占用时间
- fs.writeFile(‘路径’,‘内容’,回调(err))
-
删:
fs.unlink(‘路径’,回调) -
改名:
fs.rename(‘老文件名’,‘新文件名’,(err)=>{})
- 实现静态资源托管:
- 什么是静态资源: css/html/js/图片/json/字体…
- 前端资源请求:
- href/src/locaction.href
- 后端资源读取:
fs.readFile(文件名,[编码],回调(err,data));
url模块
1.作用:处理地址栏型数据
2.引入:const url = require(“url”);
3.使用:
- 字符转对象
- str = “http://localhost:8002/aaa?un=abc&pw=123#t4”;
- url.parse(str,true)
- true 处理query数据,直接转成对象
- 对象转字符
- url.format(obj)
- obj参数
- protocol: ‘http:’, // 协议
- slashes: true, // 双斜杠
- auth: null, // 作者
- host: ‘localhost:8002’, // 主机 www.baidu.com
- port: ‘8002’, // 端口
- hostname: ‘localhost’, // baidu
- hash: ‘#t4’, // 哈希(锚)
- search: ‘?un=abc&pw=123’, // 数据
- query: ‘un=abc&pw=123’, // 数据
- pathname: ‘/aaa’, // 文件路径
- path: ‘/aaa?un=abc&pw=123’, // 文件路径
- href: ‘http://localhost:8002/aaa?un=abc&pw=123#t4’
querystring 模块
1.作用:处理查询字符串
- var str = “key=value&key2=value2”;
2.引入:
- const querystring = require(“querystring”);
3.字符转对象:
- querystring.parse(str)
4.对象转字符
- querystring.stringify(obj)
四、包管理器 - npm
1.介绍:
- 作用:安装模块(包),自动安装依赖,管理包(增,删,更新,项目所有包)
- nodejs 环境自带 npm 环境
- 文档:https://www.npmjs.cn/
- 镜像:http://npm.taobao.org/
- 类似:bower,yarn
2.安装环境位置:
-
全局:可以独立运行 || 通过npm run 运行
- 工具命令行,脚手架
- 安装、卸载到全局
- npm i 包名 -g
- g == golbal
- yarn add 包名 | bower install 包名
- npm uninstall 包名 -g
- yarn remove 包名 | bower uninstall 包名
- npm i 包名 -g
-
项目环境:只能通过npm run 运行
- 项目依赖dependencies:
- 运行时的依赖,发布后,即生产环境下还需要用的模块。 --save || -S
- express,jquery
- 运行时的依赖,发布后,即生产环境下还需要用的模块。 --save || -S
- 开发依赖devDependencies:
- 开发时的依赖。里面的模块是开发时用的,发布时用不到它。 --save-dev || -D
- gulp
- 开发时的依赖。里面的模块是开发时用的,发布时用不到它。 --save-dev || -D
- 安装到项目环境
- npm install 包名 -S
- npm install 包名 -D
- 项目依赖dependencies:
-
查看已安装:
- 列出所有已装包
- npm list
- 版本对比(安装过的包)
- npm outdated
- 查看当前包概要信息
- npm info 包名
- 查看包历史版本列表
- npm view 包名 versions
- 列出所有已装包
3.管理模块(项目):
-
package.json的name的名字需要和项目目录名一致,不要和依赖的包重名
-
初始化npm管理文件(package.json)
- npm init
{
"name": "npm", // 项目名称
"version": "0.0.1", // 版本
"description": "test and play", // 描述
"main": "index.js", // 入口文件
"dependencies": { // 项目依赖 上线也要用
"jquery": "^3.2.1",
"express": "^4.17.1"
},
"devDependencies": { // 开发依赖 上线就不用
"animate.css": "^3.5.2"
},
"scripts": { // 命令行
"test": "命令行",
},
"repository": { // 仓库信息
"type": "git",
"url": "https://gitee.com/liyangyf/hammer.git"
},
"keywords": [ // 关键词
"test",'xx','oo'
],
"author": "小咸鱼", // 作者
"license": "ISC", // 认证
"homepage": "https://gitee.com/liyangyf/hammer.git"
}
- 安装到项目依赖 以后上线仍然需要的包
- npm install 包名 --save | -S
- 安装到开发依赖 上线后不需要的包
- npm install 包名 --save-dev | -D
- 安装package.json里面指定的所有包
- npm install
- 版本约束:
- ^x.x.x 约束主版本,后续找最新
- ~x.x.x 保持前两位不变,后续找最新
- 装最新
- x.x.x 指定一个版本
- 管理下载源工具
- 安装选择源的工具包:npm install nrm -g
- 查看所有源:nrm ls
- 测试所有源:nrm test
- 切换源:nrm use 源名
- 模块下载,卡顿超过5分钟 | 报错
- ctrl + c -> npm uninstall 包名 -> npm cache clean --force(清除缓存) -> 换4g网络 -> npm install 包名
4.其他包管理器
- yarn, bower
五、Express的安装和使用
1.介绍:
- Express 是基于Node.Js平台,快速,开放,极简的Web开发框架。类似js中的jQuery。
- 是Node.Js的第三方模块,需要安装之后才能使用
2.准备
-
首先准备好项目目录:
- 新建文件夹,在当前目录下打开命令提示符,使用npm init创建项目配置文件package.json
-
- npm install express -S
-
const express = require(“express”);
- express自身是一个函数,执行之后,拿到express对象
-
const app = express();
- 类似于const serverObj = http.createServer()
-
app.listen(端口,()=>{})
- 开启指定端口的监听,开启成功后执行回调函数
- 类似于serverObj.listen(端口,()=>{})
4.express基础使用:
- app.use(路径,(req,res)=>{});
- 当接收到指定请求路径之后,并执行对应的回调函数,一般用于注册中间件
- app.all(路径,(req,res)=>{});
- 只能接收指定请求路径的所有动作请求,并执行对应的回调函数
- app.get(路径,(req,res)=>{});
- 只能接收指定请求路径的get请求,并执行对应的回调函数
- app.post(路径,(req,res)=>{});
- 只能接收指定请求路径的post请求,并执行对应的回调函数
5.express对相应请求的方法内的req和res对象做了增强:
- req表示前端到后台的信息
- res表示后台到前端的信息
- 保留了原有属性和方法:如req.url/res.write/res.end
- 增加了:
- res.send()
- 返回数据并结束请求
- req.query
- 接收get数据,对象类型
- req.body
- 接收post数据,对象类型(需要使用中间件body-parser解析)
- req.method
- 查看当前请求方式,get/post
- res.send()
6.express的特点就是对原生NodeJs做了二次封装,非侵入式。同时某些功能需要配合中间件使用。
六、什么是中间件
1.express是一个路由和中间件Web框架,其自身的功能很少:express应用程序本质上是对一系列中间件函数调用。
2.简单的说,中间件,就是封装好的函数,类似于jq的插件,express自身的功能很少,一些功能的实现,都是通过中间件,来完成。
3.express中间件的使用:
-
body-parser中间件:
- 下载中间件:(解析post数据)
- npm install body-parser
- 引入中间件
- const bodyParser = require(“body-parser”);
- 使用并将中间件绑定到express的app对象
- app.use(bodyParser())
- 下载中间件:(解析post数据)
-
express自带的中间件:static(静态文件托管)
- 使用并将中间件绑定到express的app对象
- app.use(express.static(’./www’));
- 使用并将中间件绑定到express的app对象
4.中间件就是一个函数或对象,封装了express的功能,相对于express来说,是整个流水线上的一环。
七、express的路由介绍
1.路由是指,确定应用程序,如何响应对特定端点的客户端请求,该特定端点是URI(或路径)和特定的HTTP请求方法(GET,POST等)。
2.每个路由可以具有一个或多个处理函数,这些函数在匹配该路由时执行。
3.express的路径设置语法:
- app.METHOD(PATH, HANDLER)
- app是express的模块对象
- METHOD是小写的请求方式
- PATH是服务器上的路径
- HANDLER是匹配路径时执行的功能
- app是express的模块对象
4.如:
app.get('/', function (req, res) {
res.send('this is GET request')
})
app.post('/', function (req, res) {
res.send('this is POST request')
})
八、项目的开发方式
1.前后端分离的项目
- 前端:页面渲染
- 数据请求工具:form,ajax,…
- 后端:数据处理
- 后端管理数据库,处理数据,将数据处理成json后,通过媒介发给前端,前端接收到后端的数据,处理之后,渲染到前端页面
- 前后端可以同时开发
2.前后端不分离的项目
- 前端:静态页
- 后端:数据处理,将前端的静态页改成页面模版后,渲染
- 前端先将静态页准备好,发(U盘,QQ,仓库共享)给后端,后端将前端页面改成页面模版,后端再去请求数据,处理数据,将数据渲染到模版,将模版渲染到浏览器
3.node的后台管理项目:前后端不分离的开发方式
4.页面模版是什么:在静态页中插入后端的数据变量,逻辑语句,通过后端程序执行,得到真实的页面
九、扩展
- express中req和res的属性封装
req
- req.app:当callback为外部文件时,用req.app访问express的实例
- req.baseUrl:获取路由当前安装的URL路径
- req.cookies:Cookies
- req.fresh / req.stale:判断请求是否还「新鲜」
- req.hostname / req.ip:获取主机名和IP地址
- req.originalUrl:获取原始请求URL
- req.path:获取请求路径
- req.protocol:获取协议类型
- req.route:获取当前匹配的路由
- req.subdomains:获取子域名
- req.accepts():检查可接受的请求的文档类型
- req.acceptsCharsets / req.acceptsEncodings/ req.acceptsLanguages:返回指定字符集的第一个可接受字符编码
- req.get():获取指定的HTTP请求头
- req.is():判断请求头Content-Type的MIME类型
res
- res.app:同req.app一样
- res.append():追加指定HTTP头
- res.set()在res.append()后将重置之前设置的头
- res.cookie(name,value [,option]):设置Cookie
- opition: domain / expires / httpOnly / maxAge / path / secure / signed
- res.clearCookie():清除Cookie
- res.download():传送指定路径的文件
- res.get():返回指定的HTTP头
- res.location():只设置响应的Location HTTP头,不设置状态码或者close response
- res.render(view,[locals],callback):渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了。
- res.sendFile(path [,options] [,fn]):传送指定路径的文件 -会自动根据文件extension设定Content-Type
- res.set():设置HTTP头,传入object可以一次设置多个头
- res.status():设置HTTP状态码
- res.type():设置Content-Type的MIME类型