node.js 的祖先 瑞恩,达尔
64 位为 X64, 32 为X86
1 . 什么是Node.jss
Node.js是一个基于chrome v8引擎的javascript运行环境
2 Nodejs 和js 有什么区别
node.js 是一个js的运行环境, 与游览器 的js的执行功能一样
js 是一门强大的编程语言
1. 下载node.js
官方网站 http://www.nodejs.com
2 安装node.js
next ... finish
3 测试node.js
dos命令 node -v
4 使用node.js
1) 打开DOS 命令行
// 菜单方式
'开始菜单' -> 运行输入框 -> cmd
// 快捷键方式
wind + R =>在运行框中输入cmd
exit 退出命令行
直接在目录输入 cmd
2 运行dos 命令
e: 切换盘符
dir 显示文件及文件夹表
【mac系统】 ls
cd 进入文件夹
cd 菜单文件夹 // 进入指定的文件夹
cd ../ 返回上一级文件夹
cd / // 返回根文件夹
4 主流模块规范
js 中的模块有共性, 模块的功能代码都在一个函数中
目前主要的流行的模块规范, 分别是 AMD(require.js), CMD(seajs) Commonjs(nodejs)
都是为了实行模块化
1 模块中var定义的的变量都在模块内,为局部变量
2 模块定义在函数内,也是局部的
3 模块有一个模块对象 包含 moduleId(模块名) export (导出对象) commonjs 和 cmd 都有导出, amd 有返回值
commonjs 采用同步加载模式,只使用服务器
4 如果模块中需要暴露方法或属性给外部使用, 那么执行往exports对象中添加
AMD (异步模块定义), 之中规范是异步的模块方式
// 模块名 依赖 回调函数
define('alpha', ['require', 'exports', 'beta'], function(require,exports,beta ){
exports.verb = function(){
retur beta.verb();
});
CMD (common module definition) 是seajs 推崇的规范 玉伯
define(facgory);
defaine(function(require, exports, module){
)
CommonJS , Nodejs 采用CommonJS 的规范来定义模块
Commonjs 服务器端同步加载规范 , Node.js是这种规范的实现
二进制 二进制(0, 1) 数据对西那个(字节数组/ 或字符串)
编码 编码和字符集 utf8 GBK
io i/o 流
fs fs 基地 文件系统
系统 系统借口
断言 测试 单元
套接字 套接字 i/o
事件队列 反应堆
工人
控制台
nodejs的模块化
1。什么是模块化
在node.js中所有的功能都是一模块的形式存在的,每一个文件都是模块
所有用户编写的代码都会自动封装到一个模块中
模块之间可能存在一定依赖关系 模块之间相互独立,不相互影响
引入模块,另外一个模块需要暴露
2 。 什么是自定义模块 用户自己写的模块就是自定义模块
主模块 一个项目只允许只有一个主模块
这个模块通常命名为 main.js index.js app.js package.json 文件中的main 声明
主模块是整个项目的模块,主模块对整个项目的其他模块进行统筹和调度
node.js 的模块组成
所有用户编写的代码都在模块中, 模块就是文件(函数)
所有用户的代码都封装到一个函数中, 函数有五个参数
eports 暴露对象, 可以将模块中的数据暴露在引用的地方
require 引入模块, 用于在一个模块中引用另外一个模块,并且将自模块暴露的数据赋值给变量
module 模块对西那个 包含了当前模块的所有信息
__filename 当前模块的文件名
__dirname 当前模块所在的路径(目录路径)
require 函数
作用 在当前模块中加载另外一个模块
模块分类 1 自定义模块 我们自己编写的文件就是一个自定义模块
require('./');
a 自模块没有暴露数据是,返回空对象
b 自定义模块必须夹 './', 因为node.js中查找模块会在node_modules中寻找
2 第三方模块 第三方程序员或公司开发的模块,先安装再使用
安装使用npm 包管理工具
npm install <module_name>
3 系统模块 node.js 开发团队已经开发好的模块,直接引用即可使用,不需要安装,也不需要自己写
fs http url path
require('fs');
require 函数的注意事项
1) 当引入的模块有语法错误时,会报错
2) 当引入的模块路径错误是,也会报错
3) 多次引用相同的模块, 首先在缓存中寻找,如果缓存中存在,就取缓存中的数据,
一个模块被多次引用时, 只执行一次,景暴露对象保存在缓存中,所以执行效率高
exports 导出对象
exports 对象就是当前文档的导出对象
作用将模块中需要共享给其他模块的数据暴露到引用出(导出)
语法:
exports.属性 =值
exports.属性名 = 函数
moudule.exports == exports
注意
1) exports 是module.exports 的引用
2) exports 是module.exports 的引用,不能改指向,只能添加属性和方法
推荐使用module.exports
exports 导出对象
作用: 将模块中需要共享给其他模块的数据暴露(导出)到引用处
module 模块对象
module.exports 真正的暴露对象
module.id : 模块id 模块名称
module.parent 模块的父级
module.children 子模块的列表
module.path 模块查找路径 如果当前目录下找不到node_modules 就去上级目录查查, z回到根目录
如果配置了node_path环境变量,则会再去环境变量指向的路径查找
npm 包管理工具
js模块的基本单位是单个JS文件, 复杂的模块个由多个模块组成, 为了便于管理和使用, 我们可以由多个子模块
组成的大的模块叫做包, 并把所有的子模块放在同一个目录里。
组成的一个包的所有子模块中,需要有一个入口模块,入口模块的导出对象被作为包的导出对象。
什么是NPM
npm (Node Package Manager) 是基于nodejs的包管理工具
什么是包 包 === 项目 模块=== 文件
默认包的默认入口文件, index.js
什么 是package.json package.json 是node.js中的包描述文件, 以json格式描述项目
如何创建 package.json
npm init 初始化包
npm init -y // 全部自动以yes的形式生成package.json文件
2) package.json 的常用的属性
name: 项目名称
version 包的版本号
description 包描述
main 主模块
dependencies 依赖
devDependencies 开发时的依赖
script 脚本 可以使用npm命令执行
keywords 关键词
licence: 开源协议
3 npm 的常用命令
// 安装包的命令
npm install jquery
npm install express <包的名称>
npm i jquery 效果同上,缩写形式
npm i [email protected] //安装特定版本的包
npm i jquery -g 全局安装, window 电脑会安装在C盘的文件上,全局都可以使用
C:/Users/Administrator/AppData/Roaming/npm/node_modules
npm i <包的名称> --save //将安装包写入package.json依赖列表
npm i <包的名称> --save-dev //将安装包写入package.json 开发时依赖列表
npm i // 自动查找当前目录下package.json下的依赖,并自动安装
// 其他命令
npm search <包的名称> // 搜索包的信息
npm view <包的名称> // 查看包的信息
npm uninstall <包的名称> // 移除包的信息
npm undatae <包的名称> // 更新包的信息
4 cnpm 的常用命令 国内
npm 就是一个文件下载工具,默认情况下 npmjs.com(实际的下载地址 github.com 代码仓库,很多成型的项目)下载资源
cnpm 是taobao 提供的一个完整的 npm 镜像, 淘宝一个 cnpmjs.com 镜像
安装 cnmp
npm install -g cnpm --registry==https://registry.npm.taobao.org
5 控制台命令
console.log();
console.dir();
console.error();
console.time(标识); 计时开始
console.timeEnd(标识) 计时结束, 两个语句同时使用,确定使用的执行时间
console.assert(断言语句, 错误语句) // 断言
参数1 表达式1 当表达式为假的时候,输出错误(跑出错误)
什么是作用域
作用域: 规定了一个变量和函数可使用的范围
由于node.js会将用户编写的所有代码都封装在函数中,所有用户定义的变量和函数都是局部变量
要将数据共享给其他模块使用
1 暴露对象 module.exports 对象
2 全局对象 global global.name = 'ceshi'
异步 缓存区, 文件系统
回调函数 异步编程 Buffer缓存区(内存区是) fs文件基本操作 fs流读写方式 fs管道方式
回调函数
1。 什么是回调函数?
回调函数又称回调, 称a函数作为参数传入 b函数, b函数在执行过程中根据时机或条件决定是否调用a函数,a 函数就称为回调函数
1 回调函数的机制
1。 定义一个回调函数(非常普通的函数) 2 将回调函数的函数引用地址作为参数传递给调用者(调用者本身也是一个函数)
3。 当特定的事件或条件发生时,调用者使用函数指针调用回调函数对事件进行处理。
3 回调函数的用途
通常用于某个时机或条件时,需要执行代码的情况, 我们就会使用回调函数
异步和同步
同步: 一个任务等待
异步: 每一个任务又一个或多个回调任务, 前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是
不等前一个任务结束后就执行,所以程序的执行顺序与
同步和异步
同步: 上一行执行完欧,下一行才能得到执行
异步: 将比较复杂的任务以任务县城执行,不用等上一句执行,下一句也能执行
// 在window 最小的时间间隔为10ms
事件轮训表, 开了一个新的线程
异步的三种实现方式
1 回调函数 回调函数是异步,但异步不一定是回调函数
let arr = [1, 2, 3];
arr.forEach(function(item){
console.log(item);
})
2 事件
let http = require('http');
let server = http.createServer();
3 promise
什么是promise
promise 是ES6 的新增的对象, 用于对异步操作进行信息的传递
2 promise的状态
padding 等待中
resolved 成功
rejectd 失败
3) promise 有什么用
promise 可以用来传递异步的数据
缓存区
1。什么是缓存区 缓存区是一片内存区域,在内存中,开辟一个临时的区域用于来储存需要运算的字节码
创建长度为 10字节的Buffer实例
2 创建缓存区, 创建指定长度的缓存区
var buffer = new Buffer(大小);
(2) 按照指定的数组(编码)创建缓存区
var buffer = new Buffer([97, 98, 99, 65, 66]); 10进制的编码
(3)按照指定字符创建缓存区
var buffer = new Buffer('张三');
let buffer = new Buffer('lisi')
在GBK模式下,中文占两个字节, 在utf-8下 中文占3个字节
所有的数据都是以字节流传递,
(4) 写进缓存区 buf.write('张三');
(5) 读取缓存区 buf.toString();
(6) 复制赋存取 buf1.copy(buf2);
文件系统的操作
1。 读取文件
由于node.js是服务器的程序, 必须要有读写文件操作, 在客户端没有这种功能
文件读写有两种方式
1。 直接读取
将硬盘上的所有内容读入内存以后才触发回调函数
直接读取分两种情况
1。 同步读取
let fs = require('fs');
2。 异步读取
2。 流式读取
将数据从硬盘中读取一节就触发回调函数,实现大文件操作
(1)同步版本
fs.writeFileSync()
(2)异步版本
fs.writeFile('文件名', 数据, function(err){})
3 读取文件信息{
fs.state('文件名', function(err, state){
state包含了常见的文件信息
Stats {
dev: 16777221,
mode: 33188,
nlink: 1,
uid: 501,
gid: 20,
rdev: 0,
blksize: 4096,
ino: 2605688,
size: 1, 文件大小
blocks: 8,
atimeMs: 1573779437300.269,
mtimeMs: 1573779435558.5244,
ctimeMs: 1573779435558.5244,
birthtimeMs: 1573351618276.2988,
atime: 2019-11-15T00:57:17.300Z,
mtime: 2019-11-15T00:57:15.559Z, 修改事件
ctime: 2019-11-15T00:57:15.559Z,
birthtime: 2019-11-10T02:06:58.276Z 文件创建事件
}
})
计算机基础, 计算机网络基础, tcp协议 数据结构
console.log(data.isFile()); // 获取
console.log(data.isDirectory());
fs.stat('./', function(err, data){
console.log(data);
});
fs 删除文件
fs.unlink(path, callback);
fs.unlink('./index4.html', function(err, data){
if (err){
throw err;
} else {
console.log('文件删除成功');
}
})
递归删除非空目录
1. 删除空目录
fs.rmdir();
2. 删除非空目录
(1) fs.readdir 读取目录中的文件及文件夹列表
(2) 判断是否为文件 fs.stat()
(3) 如果是文件 fs.unlink();
(4) 判断如果是目录 递归调用自己
(5) 删除内部文件空文件
(6)删除空目录
delDirFunc('./data')
function delDirFunc(dir) {
let list = fs.readdirSync(dir);
for (let i = 0, len = list.length; i < len; ++i){
let path = dir + '/' + list[i];
let status = fs.statSync(path);
if (status.isFile()) {
fs.unlinkSync(path);
} else {
arguments.callee(path)
}
}
fs.rmdirSync(dir);
}
1. 什么是流?
所有互联网传输的数据传输方式都是以流的方式,数据的传输都是一节一节的。流是一组有起点有重点的传输的方式
数据的传输是一段一段的,流就是字节。流是有起点有终点的数据传输方式
流的操作有两种情况
1。流式读取, 64kb
let fs = require('fs');
// 创建可读流
let readStream = fs.createReadStream('./file.txt');
可读流的数据监控
readStream.on('data', function(data){
console.log(data);
console.log(data.length);
});
// 可读流完成
s1.on('end', function(){
s2.end();
console.log('文件复制完成');
});
2。流式写文件 chu
let fs = require('fs');
// 创建可写流
let writeStream = fs.createWriteStream('./file3.txt');
// 写入流写入数据
writeStream.write('张三失踪了');
writeStream.write('李四失踪了');
writeStream.write('王五失踪了');
// 写入流写完数据提醒
writeStream.end();
// 写入流的事件, finish完成
writeStream.on('finish', function(data){
console.log('写入完成');
});
writeStream.on('error', function(err){
console.log('出错了');
});
管道提供了一种输出到输入的机制,通常我们用于从一个流中获取数据并将数据传入到另外一个流中
输出流.pipe(输入流)
let fs = require('fs');
// 使用管道实现文件复制
let s1 = fs.createReadStream('./file.txt');
let s2 = fs.createWriteStream('./file6.txt');
s1.pipe(s2);
8 链式流
链式流通过链接输出流到另外一个流并通过创建多个对个流操作链的机制,链式流一般用于管道操作
链式调用,可以制作压缩文件
读取文件流,并压缩,再写入文件流, 文件的压缩都是一节一节的压缩
将多个管道链接起来,实现链式处理, 大文件的压缩
9 网络地址和http模块
1. path 路径
path模块是node.js中提供的一个系统模块,
用于各式化或者拼接一个完整的路径
常用的方法
1) 规范化的路径 path.normalize(网址);
2) path.join() 将多个字符串进行拼接
3) path.resolve() 转换为绝对路径
/user /root都是绝对路径
www.baidu.com 都是绝对路径
4)path.isAbsolute() 判断是否为绝对路径
5) path.relative() 转换为相对路径
6) path.dirname() 返回字符串中的文件部分
7) path.basename() 返回字符串汇中的文件名和扩展名
8) path.extname() //返回路径中的扩展名部分
9) path.parse() 返回路径中的各个部分
{
root: '',
dir: './day02/hello',
base: 'zs.html',
ext: '.html',
name: 'zs'
}
2. url 网址
url 模块
全球统一资源定位符,对网站资源的一种简洁表达形式,
也称为网址。
www.baidu.com
www // 主机名
baidu.com // 域名
zhibao.baidu.com
// zhidao 部分为二级域名,可以无限的增加
/ 表示根目录
url 的构成:
1) 一个url字符串是一个结构化的字符串,它包含很多部分
ulr包含两种模式,新旧模式
旧的模式包含
1).htpps 表示协议
2). http协议 https:// 表示协议
https://user:[email protected]:8080/p/a/t/h?query=string#hash
3) auth 用户名和密码 dengyunfa:tongpeng,使用冒号隔开,
/表示根目录/
参数名=参数值 使用get方式传递参数
hash地址,可以作为前端路由,又可以用作锚点
wwww 为主机名或二级域名
4)协议://用户名:密码@主机名.名.域:端口号/路径名/文件名.扩展名?参数名=参数值&参数名=参数值#hash地址
一些网站访问,采用匿名访问
//http协议的url 常见结构
前端路由的转换
协议://主机名.名.域/目录名/文件名.扩展名?参数名=参数值&参数名2=参数值2#hase
https://www.baidu.com/img/bd_log1.png
http://
3306 myspl
端口号: 2的16次方-1
1000以下的端口,操作系统或应用的端口、
10000以下的端口,其他应用程序的端口
可以使用10000以上的端口 65535的端口
4. node.js的URL模块
在node.js 中提供了两套对于url进行中处理的api
1) 老的node.js url模块
let url = 'http://msuic.163.com:80/aaa/index.html?id=10#/discover/playlist';
let url = require('url');
let url1 = 'http://msuic.163.com:80/aaa/index.html?id=10#/discover/playlist';
// 老得node.js url模块
console.log(url.parse(url1));
Url {
protocol: 'http:', // 协议名称
slashes: true,
auth: null, // 身份验证
host: 'msuic.163.com:80', // 域名和端口
port: '80', // 端口
hostname: 'msuic.163.com', // 域名
hash: '#/discover/playlist',
search: '?id=10',
query: 'id=10',// 查询名
pathname: '/aaa/index.html', // 路径名
path: '/aaa/index.html?id=10',// 路径和参数
href: 'http://msuic.163.com:80/aaa/index.html?id=10#/discover/playlist'
}
2) 新的 url模块(WHATWG url模块)
let obj = new url.URL(url1);
console.log(obj);
console.log(obj.host);
URL {
href: 'http://msuic.163.com/aaa/index.html?id=10#/discover/playlist',
origin: 'http://msuic.163.com',
protocol: 'http:',
username: '',
password: '',
host: 'msuic.163.com',
hostname: 'msuic.163.com',
port: '',
pathname: '/aaa/index.html',
search: '?id=10',
searchParams: URLSearchParams { 'id' => '10' },
hash: '#/discover/playlist'
}
http协议
什么是网络
网络是信息传输,接受,共享的虚拟平台。
网络传输数据都有一定的规则,这些规则我们成为协议,http就是规则的
一种
什么是网络 网络是一个共享,传输信息的虚拟平台
什么是网络协议
什么是http协议
http(hyper text transfer protocal)超文本传输协议
传输文本内容(文本,图片,视频, 音频,动漫等);
http协议规定了数据在服务器与游览器之间传输数据的格式和过程
详细的过程为三次握手
http协议规定的细节
http 协议是一种请求应答形式的协议,一次请求,一次应答,
http协议,不能自动发送信息给客户端
细节
定义了游览起以什么格式向服务器发送请求
定义了服务器以什么格式解析游览起发送的请求
定义了服务器以什么格式响应数据给游览起
定义了游览起以什么格式解析服务器响应的数据
5 软件开发模式
1 单机模式
打开电脑就能能用, 不需要网络,如hbuild word
2 c/s软件
client /server
需要下载安装后,才能链接网络使用,如迅雷,QQ, 微信
3 b/s软件
游览端brower / 服务器端server
打开网络就能直接使用,不需要安装,百度, 京东,淘宝
http模块
node.js中的http接口被设计成支持协议的许多特性, 比如,大块编码的信息,这些接口不缓冲
完整的请求或响应。用户能够以流的形式处理数据,http信息头由一个对象表示,例如。
1.get 方法 get方法用于模仿客户端从服务器获取数据,后段没有跨域问题
http.get('url', function(res){
});
res是返回对象,它是服务器端的所有内容, 它是http.incomingMessage的一个实例
05 网络爬虫程序
1。什么是爬虫
什么是爬虫,又称网络爬虫,是一种自动获取网页内容的程序
又称,网页蜘蛛,或者网页机器人。按照一定规则,自动从万维网抓取信息
2. 写一个爬虫程序从nipic.com批量下载图片
url: http://www.nipic.com/photo/jianzhu/shinei/index.html
http.get('http://www.itsource.cn', function(res){
res.on('data', function(a){
console.log(a.toString());
});
// 获取说有的页面信息
res.pipe(fs.createWriteStream('./index.html'));
});
开发思路
1) 打开网页查看内容,找图片地址
找规律=》 查看网页源代码
小图 http://pic254.nipic.com/pic/20191120/6958543_112545910831_4.jpg
大图 http://pic254.nipic.com/file/20191120/6958543_112545910831_2.jpg
小图 http://pic252.nipic.com/pic/20191116/19809146_091319922117_4.jpg
大图 http://pic252.nipic.com/file/20191116/19809146_091319922117_2.jpg
2) 编写代码实现打开网页,获取所有的html内容
3) 通过正则表达式提出到哪些图片地址
4)遍历图片地址数组,一个一个请求
5) 将获取到的图片保存在硬盘上
let http = require('http');
let fs = require('fs');
let data = '';
http.get('http://www.nipic.com/design/acg/index.html', function (res) {
res.on('data', function (a) {
// 以流的方式读取数据
data += a.toString();
});
res.on('end', function () {
// 获取到的当前网页的html内容
// console.log(data);
//
fs.writeFileSync('./data.html', data);
let result = '';
let reg = /<img src=".+?" data-src="(.+?)" alt=".+?" \/>/img;
let arr = [];
while (result = reg.exec(data)) {
arr.push(result[1]);
}
fs.writeFileSync('./file.txt', arr);
for (let i = 0, len = arr.length; i < len; ++i) {
(function (i) {
setTimeout(function () {
getImg(arr[i]);
}, i * 1000);
})(i)
}
});
});
function getImg(src) {
console.log('修改前:', src);
src = src.replace('\/pic\/', '\/file\/').replace('4.jpg', '2.jpg');
console.log('修改后:', src);
/// http://pic251.nipic.com/file/20191108/29591675_000132608085_2.jpg
http.get(src, function (res) {
let name = (new Date()).getTime();
let writeStream = fs.createWriteStream('./files/' + name + '.jpg');
res.pipe(writeStream);
});
}
回调函数
1)什么是回调函数
回调函数也称为回调,其实就是一种普通的函数,也将函数作为另外一种函数的参数传入,由另外一个函数根据条件
2)回调函数的实现机制
a. 定义一个普通的函数(作为回调函数)
b.将该函数作为一个参数传入另外一个函数(调用中)
c.调用者函数在具体的时机或条件达到时,调用改函数(回头再调用该函数)
3)回调函数的作用
如果我们需要在某一个任务完成后,执行一段代码后,可以使用回调函数
2 异步和同步
1) 什么是异步与同步
同步 前一个任务完成以后,后一个任务才能继续执行(会造成阻塞)
异步 将计较复杂的任务制作成异步模式(回调函数),后一句代码不需要等待前一句完成后才可以继续执行(不会造成阻塞)
2) 异步的实现
a 回调函数
异步一定有回调函数,回调函数不一定是异步(一些同步的情况下也会用到回调函数)
b 事件
触发事件以后执行一个回调函数,就是异步
事件源.on(事件类型, 回调函数)
c promise
promise (承诺对象),实现异步的信息传递
3) buffer 缓存区
2) 什么是缓存区
缓存区就是内存中的开辟的存储空间,用于存储字节数据
2 缓存出操作
a.创建新的缓存区
var buf = new Buffer(10);
var buf = new Buffer([97, 98);
var buf = nwe Buffer('张三');
b.读取缓存区
buf.toString(); // 将字节码转换为字符串
c 写缓存区
buf.write('字符串');
d 复制缓存区
buf.copy(buf2);
4 文件的基本操作(直接操作)
1) 读取文件内容
fs.readFile('文件路径', function(err, data){
// error 是错误对象,如果有错误则有值,没有错误则为 null
// data 是数据(字符集)
});
// 同步: 只要在异步的方法名后面加Sync就是同步版本
let data = fs.readFileSync('文件路径');
// 同步如果遇到错误,则抛出错误,停止执行
2) 读取文件信息
fs.stat('文件路径', function(err, data){
//
}
)
path模块
path.join 拼接路径,拼接一个完整的路径
path.parse 返回一个对象,包含路径中的各个部分
url模块
什么是url 全球统一资源定位符,也称为网址
url的结构
协议://用户名:密码@主机名.名.域:端口号/路径/文件名.扩展名?参数名=参数值&参数名=参数值?hash值
常见的结构
协议://主机名.名.域名:端口号/路径/文件名.扩展名?参数名=参数值&参数名=参数值?hash值
在node.js中提供了liangtaoAPI接口,用于解析URL地址
url.parse() 原有的node.js功能
new url.URL() // 按标准解析功能
http协议 网络协议的一种, 是TCP/IP协议族中的一个顶层协议或应用协议
规定了服务器与客户端如何进行数据传输,传输格式和传输方式
http协议采用请求/应答模式,一次请求,一次应答。
http模块
http模块是node.js中的网络通信模块,可以作为客户端向服务器发起请求,
也可以作为服务器向客户端响应数据
http.get() // 获取数据,可以作为客户端向服务器发起请求,并获取数据
http.get('url', function(响应对象){
// 响应对象是一个数据流对象,
})
web socket可以用作直播平台,
爬虫, 机器人,蜘蛛
tcp/ip 网络控制和网络协议又命名为网络通讯协议
互联网总共7层网络结构,最顶层为应用层,最顶层为与用户接触最多的
物理层: 网线,路由器
网络层 网卡
应用层的协议包括ftp, dns, http. nfs smtp
http协议是超文本传输协议的简写, 是一种网络传输协议,采用的是请求/应答方式传输数据
http协议到底约束了什么
1.
http 请求包含的东西
请求头部
1。accept 接受的东西
5 accept-language 语言
2. user-agent 用户代理
3 host 请求主机
4 connection 拦截转台
6 cache-control 缓存控制
7 accept-encoding 编码格式
2 请求的基本部分
request url 请求地址
request method 请求方式
status // 服务器地址
remote address 服务器地址
3 响应头部分
1. data
2 connection
访问服务器
1) 打开游览起 2) 输入网址 127。0。0。1 本机地址
localhost 当地主机,本地域名
局域网 ip 172
let server = http.createServer();
// 监听request请求事件,当前请求事件发生时返回数据
server.on('request', function(req, res){
// req 请求对象,包含了所有客户端请求的数据,请求头,请求主体
// res 响应对象, 包含了所有服务器端发给客户端,响应头,响应主体
res.write("<h1>hello node.js</h1>");
res.write("<h1>hello 111</h1>");
res.end();
});
// 监听服务器的80端口
server.listen(80, function(){
console.log('开始监听了');
});
// node.js 服务器
let http = require('http');
// 创建服务器
let server = http.createServer();
// 监听request请求事件,当前请求事件发生时返回数据
server.on('request', function(req, res){
// req 请求对象,包含了所有客户端请求的数据,请求头,请求主体
// res 响应对象, 包含了所有服务器端发给客户端,响应头,响应主体
res.write("<h1>hello node.js</h1>");
res.write("<h1>hello 111</h1>");
res.end();
});
// 监听服务器的80端口
server.listen(80, function(){
console.log('开始监听了');
});
// node.js 服务器
访问服务器
1。 引入htpp let http = require('http');
2. 创建服务器 let server = http.createServer();
3. 监听request请求
server.on('request', function(req res){
res.write("<h1>hello node.js</h1>");
res.write("<h1>hello 111</h1>");
res.end();
});
根据用户请求的地址,返回不同的内容
if (req.url === '/') {
res.write('<h1>homepage</h1>')
} else if (req.url === '/article'){
res.write('<h1>article</h1>')
}
else if (req.url === '/about'){
res.write('<h1>about</h1>')
}
res.end();
netstat -a // 查看所有的端口
scheme 协议
host 定义域主机(http 的默认主机为www)
domain 定义域名的主机
port 端口
path 定义服务器的路径
filename 定义文档/资源的名称
queryName 查询字符串
http响应的状态码
http协议规定了服务器响应数据时的状态编码,就是状态码
1。 常用的状态码:
1XX 普通消息,表示不同消息,没有任何含义
2XX 服务器响应成功
200 请求成功
3XX 表示重定向
301 永久重定向, 网站地址更改 网站改版
302 临时性的重定向, 网站维护
304 使用缓存,服务器内容未更新
4XX 无法访问
400
401 身份验证
403 服务器理解请求,但拒绝执行, 无权限
404 请求失败,请求资源不存在
5XX 服务器执行有错,
500 服务器代码错误
502 网关或者代理错误
503 服务器已经崩溃
res.writeHead(状态吗, 响应头);
Content-Type: 响应的文件类型
text/html // 未指定响应类型的时候,默认为html
Content-Length 响应内容的长度
2000
"Access-Control-Allow-Origin": '*' // 设置跨域问题
res.writeHead(200, {
"Content-Type": "text/html; charset=utf-8",
"Content-Length": 24,
"Access-Control-Allow-Origin": '*'
});
Mime类型, 文件类型的表述,以扩展名的方式表示
多种格式的邮件类型
任意类型的文件都转换为base64 格式类型
设置某种格式的文件,使用文件格式打开
常见的文件类型表示
.html text/html text/plain
.css text/css
.js text/javascript
.png image/png
.jpg image/jpg
.gif image/gif
.json text/json application/json
.mp3 audio/mpeg
.mp4 video/mpeg
.pdf application/pdf
.xml text/xml;
.zip application/x-gzip
// 可以使用后端语言生成
客户端向服务器传送数据的方式
1。 get请求
// 创建服务器
let server = http.createServer();
server.on('request', function(req, res){
let query3 = req.url.split("?");
let query3String = query3[1];
let data3 = query3String.split('=');
let value3 = data3[1];
res.writeHead(200, {
"Conent-Type": "text/html; charset=utf-8"
});
res.write('<h1>参数为=' + value3 + '</h1>');
res.end();
});
server.listen(80, function(){
console.log('server is running');
});
2。 post请求
if (req.url === '/action.html') {
let query = '';
req.on('data', function(a){
console.log(a.toString());
query += a.toString();
});
req.on('end', function(){
res.writeHead(200, {
"Content-Type": "text/html; charset=utf-8"
});
res.write('<h1>我们已经收到了请求</h1>');
res.write('<h1>我们接收到的数据为 '+ query +'</h1>')
res.end()
});
return false;
}
静态网页:
不会随着时间,参数,客户端的改变而改变,网页内容是固定不变的
动态网页
网页随着时间,参数,客户端的改变而改变的页面
使用动态网页模版
1。 什么是模版
将一些固定的结构或表现直接以静态文件形式存储,
将需要表现成动态数据地方是否用模版
// 获取某个服务器的图片
https.get('https://www.itsource.cn/', function(res){
let str;
res.on('data', function(a){
str += a;
});
res.on('end', function(){
fs.writeFileSync('./indexCopy.html', str);
let reg = /url\(\/upload(.+?)\)/g;
let arr = [];
let result = '';
while(result = reg.exec(str)){
arr.push(result[1]);
}
console.log(arr);
});
});
1 express 后端,react, vue都需要
epress 是一个基于node.js平台的极简,灵活的web应用开发框架
可以实现非常强大的web服务器公共
2。 express的特点
1)可以设置中间件, 响应或者过滤http请求
2) 可以实现路由实现动态页面,响应不同的http请求
3) 内置支持egj模版(默认是jage模版) 实现模版渲染生成html
3 express-generagor 生成器
express-genenator是express 官方团队为开发者准备的一个快速生成工具express开发框架
可以非常快速的生成一个基于expres开发
4 express 安装与使用, 首先安装express 生成器
1) 安装express-generator 生成器, 为了更好的使用 express框架
cmpm i -g express-generator // 安装完成后可以使用express 命令
2 创建项目
express -e 项目名称 // 自动创建项目目录 使用什么模版 -e 就是使用 egg.js模版
express -e // 手动创建项目目录 使用jade模版
3 安装依赖
cmpm i // npm install
4 开启项目
node app
在app.js文件需要增加
app.listen(80, function(){ // 需要手动添加
console.log('默认启动项目')
})
node start "start": "node ./bin/www" // 默认比较慢
在package.json 里面的script 找到start命令,进行执行
node ./bing/www
5 测试项目
打开游览起 输入localhost
express 框架 文件目录
目录
1 bin 可以执行文件目录, 可以删除
2 node_modules 项目依赖文件夹
3 public 静态文件根目录, 所有的静态文件都应放在这个文件夹
文件包含 html css js image 视频和字体文件
4 routes 动态文件目录 动态文件的目录
优先找静态文件,如果没有静态文件,再找动态文件
如果没有动态路由,就404
5 views 视图目录 用于储存ejs模版
2 文件
app.js 项目的主文件,对整个项目的资源进行统筹安排
对整个项目的所有资源进行统筹
package.json node 项目的描述文件
声明项目的名称,版本 依赖信息
mongodb-macos-x86_64-4.2.1
路由 是如何定义应用的端点, 定义不同的网址,响应用户的请求
路由,接收用户请求, 处理用户数据,返回结果给用户的一套程序
可以理解为生成动态网页的程序
后端路由的核心: URL
express的路由
express对象自带有一个routeer类,可以实例化路由对象,可以在该对象上挂载很多的节点
// 编写一个新闻列表的路由
router.get('/news.html', function(req, res){
res.send("<h1>这里是一个新闻列表</h1>");
});
4 创建一个独立的路由模块
// 需求, 创建一个vip模块,
创建一个独立的路由模块
// 需求,创建一个vip独立模块
编写路由模块的代码
a. 引入express 模块
b. 并 创建router对象
c 编写路由,挂载到路由对象上
d 暴露路由对象
3) 将编写号的路由模块引入到主模块,由主模块分配对应的请求到该模块去处理
let vipRouter = require('./routes/vip.js');
app.use('/vip', vipRouter);
5 路由的区分
大路由器, : app.js 负责接受所有的请求,并对请求进行分配
小路由; (分路由) /routes 下面的所有的路由模块, 只负责处理自己能管理的目录下的请求
响应对象
1) 响应对象, 是只服务器向客户端响应数据的对象,包含了所有响应的内容
2) 响应对象的方法
res.send() // 返回任意类型的数据给客户端
// res.send('hello world');
let data = {"name": "李白", "age": 99};
res.send(data);
注意
a : 如果返回数字, 会当成状态码
// res.send('1') // 如果要返回数字,必须加引号,变成字符串
res.status(200).send('fsdfsdf)
res.status(200);
res.send('fsdfsdffsdf');
res.json(data) // 返回json数据
res.render() // 视图模版控制
res.render('模版名称‘, {}) // 读取模版文件,拼接数据,自动将结果发送给游览器
let data = [
{"name": "李白", "age": 18},
{"name": "李黑", "age": 19},
{"name": "李太白", "age": 20}
];
res.set({"Content-Type": "text/html; charset=utf-8"});
res.render('list', {users: data});
下载文件
res.download('./xxx.doc') 下载当前目录下面的xxx.doc文件
res.download('./xxxx.doc, 'yyy.doc')
// 下载当前目录的xxx.doc文件,并且重命名为yyy.doc文件
// 重定向,实现服务器端的跳转
res.redirect('http://wwww.baidu.com')
res.set({}) // 设置响应头
res.type(); //
res.status()
// 请求对象
1) 什么是请求对象
客户端向服务器发送数据的对西那个,包含了请求头和请求主体
2) 接受get 请求方式传递的只
语法 req.query // 参数名这
router.get('/content.html', function(req, res){
console.log(req.query)
let id = req.query.id;
id = id ? id : ''
res.send("<h1>这里是一个新闻列表: " + id+"</h1>");
});
3) 接受数据
router.get('/content.html', function(req, res){
console.log(req.query)
let id = req.query.id;
id = id ? id : ''
res.send("<h1>这里是一个新闻列表: " + id+"</h1>");
});
4) 匹配url网址的数据
在接请求地方匹配,在通过语法方式进行接受数据
语法: req.parsms.参数名
伪静态数据
router.get('/news3:id', function(req, res){
let id = req.params.id;
res.send('<h1>接收到的参数为:'+ id + '</h1>')
});
router.post('/login.html', function(req, res){
let userName = req.body.username;
let pwd = req.body.pwd;
console.log(userName,pwd );
res.send("<h1>这里是一个新闻列表: </h1>");
});
express 是一个自身功能极度简单,完全是由路由和中间件构成的一个web开发框架
中间件
1) 什么是中间件
中间件是一个函数, 位于客户端和路由之间,也可以调用下一个中间件
express 是由中间件构建起来的框架
2) 自定义中间件
app.use(function(req, res, next){
res.send('我是中间件)
});
3) 尾函数next
如果中间函数不调用next函数,整个请求响应流程
中止不再往后面执行
调用尾函数相当于调用下一个中间件
什么是网络协议
网络就是信息传输和共享的平台,
什么是网络协议
信息在网络上传输是必须按照一定的规则,这套规则就是网络协议
http 协议 stmp 协议 ftp 协议
http 协议约束了
1. 约束了游览起以何种格式向服务器发送数据
2. 约束了服务器以何种格式来接受客户端发送的数据
3. 约束了服务器以何种格式来返回数据给游览起
4 约束了游览起以何种格式来解析服务器反馈的数据
网络请求与响应运行原理
1. 将用户输入的网址,找dns服务器解析成ip地址
2. 根据ip地址请求服务器(请求头和请求主体)
静态网页
3) 服务器接受到请求判断请求的网页是一个静态网页
4) 如果是静态文件就直接从硬盘中读取,返回(html)给游览起
动态网页
5) 服务器接收到请求, 判断请求的网页是一个动态网页
6) 如果是动态网页,则找到动态网页生成程序,实现生成html 代码, 返回给客户端游览起
执行动态程序
读写数据库
将数据处理完成
读取模版文件
使用模版引擎景模版与数据进行整合
生成html代码
4 http 状态码
1) 什么是状态码
http 状态码是服务器响应数据给客户端的状态编码, 由3个数字组成
2 http 常见的状态码
200 正常 301 永久重定向 304 文件未修改 ,可以使用缓存
404 资源找不到 500 服务器执行有错
5 mime 类型
1) 什么是mime类型
数据库的介绍
数据库 database, 是一个按照数据结构, 进行数据的组织,管理, 存放数据的仓库
关系型数据库, 大众部分, 表格部分
按照关系模型存储数据的数据库, 数据与数据之间的关系非常密切,可以实现跨数据查询数据
占用更少的硬盘,实现更多的数据存储
t-sql 标准化的结构化查询语言
是关系型数据库的通用查询语言
常见的关系型数据库 mysql sql-server access sqllite
包含的数据,性别,姓名,年龄,住址信息
服务器包含多个数据库,一个数据库包含多个表格,一个表格包含多行 ,
一行数据包含 性别,姓名,年龄,住址信息
非关系型数据库 小众部分 集合部分
不是按照关系型模型存储数据的数据库, 统称 nosql
一层含义 不是sql 第二层含义, not only sql 不仅仅是sql
服务器包含多个数据库,一个数据库包含多个集合,一个集合包含多个document
document 就像json 数据, json数据就可以存放在mongodb
nosql 用于超大规模数据的存储,
mongodb 是基于分布式文件存储的数据,由C++
是世界上用得最多的非关系型数据库,也是最像关系型的非关系型的数据库
1. mongo.exe 负责使用数据库
mongod.exe 负责mongo的开关机
设置环境变量
1.将bin路径进行复制。 2. 点开计算机-属性- 高级系统设置-gao
环境变量分为 系统环境变量和应用环境变量,只可以更改应用环境变量
当无环境变量的时候,进行新增, 如果有进行修改
路径名字为PATH 修改需要加分号,然后再增加
4 将mongodb挂载成window服务
1) 使用命令挂载服务
mongod -dbpath "d:\mongodb\db" --logpath "\d:\mongodb\log\mongodb.log" --serviceName "mongodb"
设置变量 和 日志目录, 和设置为服务
服务信息查看
在计算机上鼠标右键,-》 管理 -》 服务与应用程序 -》 服务
show dbs 展示数据库
补充说明服务的命令
net start mongodb // 开启服务
net stop mongodb // 关闭服务
sc delete mongodb // 卸载服务
mongodb 基本的命令
1. 进入数据库管理模式
命令行中运行,mongo 进入数据库管理模式
在数据管理模式中, 只能记性书库哭命令, 不能执行其他命令
exit // 退出数据库管理模式
常用的命令
1. 数据库的命令
a. 显示所有的数据库列表命令
2 创建数据库 use 数据库名
如果数据库不存在,就创建, 如果数据库存在,则进入
3 .从 查看当前数据库是谁
db
4 删除数据库
db.dropDatabase();
2 集合的命令
a 显示当前数据库中的所有集合
show collections
b 创建结合
db.集合名.insert({})
通常在创建数据的时候,自动创建集合,不需要单独创建
c 删除集合
db.集合名.drop()
3 数据的操作,增删改查
a 新增文档(数据)
db.集合名.insert(json)
db.集合名.save(json)
insert 和 save 的差别
insert 单纯的向集合添加数据, 推荐使用,比较清晰
saven 也西那个数据库中添加数据,如果已经存在数据,则为更新
db.user.find() 查看所有的数据
use admin;
switched to db admin
> db.shutdownServer();
b 查询文档(数据)
db.集合名.find() // 查找当前集合的所有的数据
db.集合名.find({条件}) // 符合条件的数据都被查找出来
db.user.find({"name":"童鹏"})
db.user.findOne() // 查找第一条数据
db.集合名.find().pretty() // 以对象的格式展示数据
修改数据
db.集合名.update({查找对象}, {更新对象}) // 数据全部替换
db.user.update({"name":"tongpeng"},{$set: {"name":"tongwei","age":31}}) 部分替换
删除数据
db.user.remove({}) // 删除所有的数据
db.user.remove({"name": "刘备"})
高级查询命令
// 需求, 查找所有的女星
db.user.find({"name":"刘德华"}).pretty()
db.user.find({"name": "留的华", "country":"中国"})
sql语句的写法
select * from singer where sex = "女"
select * from singer where sex = "女" and country="中国"
// 需求查找年龄大于30的 所有数据
db.collection.find({"key":{{$gt: 50}}})
// 年龄大于28的
db.user.find({"age":{$gt: 28}})
// 大于等于
db.user.find({"age":{$gte: 28}})
db.user.find({"name":"tongwei","age":{"$gt":21}})
7)大于多少 且小于大值
db.user.find({"age":{$gt: 30, $lt: 40}}).pretty();
sql
select * from user where age > 30 and age < 40
8 ) 查找指定范围的数据
db.user.find({"key": {$in: ['tongpeng']}});
//
db.user.find({"name":{$in: ["童鹏","tongwei","童芬"]}})
db.user.find({"name":{$nin: ["童鹏","tongwei","童芬"]}})
9) 按照数组中元素的个数查找
db.集合名.find({"key": {$size: 3}});
db.user.find({"works": {$size: 1}})
10) 查找两个条件中,符合其中一个条件的数据
db.user.find({$or: [{a:1}, {b: 2}]})
db.user.find({$or: [{"name":"tongwei"},{"age": 21}]}).pretty()
11) 不等于
db.user.find({"name": {$ne: "tongpeng"}})
12 排序 按照age 进行排序, 'age' 升序排列
1. 表示升序排列, -1 表示降序排列
db.user.find().sort({"age": -1})
13 限定输出 limit skip
limit 限定输出数据的条数
skip 跳过多少条数据
db.user.find().sort({"age": 1}).limit(3)
显示年龄递增,的三个数据
扩展, 这两个限定输出的语句主要用于分页
属兔太多, 在一个页面显示不完,可以分成多个页面显示数据,就是分页
14 模糊查询
db.user.find({"name": /刘/i}) 模糊查询
i 表示忽略大小写信息
express 的概念
1) 什么是express
express 是一个基于node.js 的快速实现web应用的框架
2) 安装
a) 安装生成器
cnpm i -g express-generator
b) 创建项目
express -e 项目名称
c 安装依赖
进入项目项目目录
cnpm i // 自动查找当前目录下的package.json文件,找到依赖列表
d) 运行项目
node app
npm start // 自动查找目录下的pageage.json文件, 找到scriptes 里面的
start 命令 , 执行对应的命令
node ./bin/www // 默认将开3000端口
e) 检测项目
手动代开游览起, 输入
手动代开游览器,输入:
2) 路由
1 什么是路由?
路由是指接受用户请求,处理用户数据,
返回运行结果的一套程序
2 路由的分类, 路由分为
大路由 app.js 用户接受所有用户的用户请求,并进行分配
和小路由 routes目录下的所有的路由模块,
用于执行请求返回的数据, 只能处于当前路由下的请求
3 路由的写法
// 在routes 目录下创建一个独立的路由模块, (也可以修改路由模块)
b 编写模块代码
var router = require('express').Router();
// 挂载路由
router.get('url', function(req, res, next){
res.send(')
});
module.exports= router;
c 将编写好的路由模块挂载到 app.js中
var vip = require('./routes/vip.js'); // 引入模块
// 分配/vip目录下的所有请求的都让 vip模块去处理
app.use('/vip', vip);
3. 响应对象
.send() 响应任意类型的数据给客户端
.json() 响应json数据给客户端
.status() 设置响应的状态码
.render() 渲染后端模版
.set() // 设置响应头数据
4 . 请求对象
接受get 请求方式传的值 req.query.params
req.body // post 方式传递的数据
req.ip
req.url
5 中间件
1) 什么是中间件,就是一个函数, 就是在请求的时候执行。路由也是一个中间件
位于客户端和
所有的express 功能都是 以中间件形式实现
moogose
1. 什么是mongose?
mongoose 是基于 node.js的,用于操作mongodb数据的第三方模块
2 mongose的安装
npm install mongose 首先要有express 框架
3 mongose的使用
1) 链接数据库
use admin 进入admin数据库
>db.createUser( {user: "admin",pwd: "123456",roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]})。 增加用户admin 权限 操作用户所有的数据库d
// 创建骨架, 就如同工厂的茶具
定义 骨架 schema 概述。schema 骨架是一种数据结构说明 ,不具备数据库的操作能力
语法:
Var schema = new mongoose.Schema({
字段名: 类型,
字段名: 类型
})
实例;
Var singerSchema = new mongoose.Schema({
name: String,
country: String,
age: Number
})
骨架的类型: String, Number, Date, Buffer ObjectId Array
3) 创建模型. 概述。由schema 发布生成的模型 ,具有抽象的属性和行为,可以对数据库进行操作
根据骨架创建出来的模型,具有数据库操作行为,可以用来读取数据库
// 通过模式 studengSchema.
var singerModal = mongoose.modal("模型名称", 骨架, 集合名称)
实例:
var singerModel = mooogoose.mongel(')
4) 创建实体, Entity. 一种根据模型创建出的一个实例, 具有数据库操作的能力, 通常用于读写数据(新增,修改,删除)
var singer = new singerModel();
Singer.属性名 = 值
Singer.save(); // 将添加到实例的属性保存到数据库中
4。数据操作(增删改查)
1) 查询数据/读取数据
模型.find
// 查询所有的书
router.get('/', function(req, res, next) {
userModal.find({}, function(err, data){
res.send(data);
});
});
根据id 查询
userModel.findById('5de8c300fa266319ca0e2b27', function(err, data){
res.send(data);
});
根据id查询 链式调用, 可以重复调用
userModel.findById('5de8c300fa266319ca0e2b27').exec(function(err, data){
res.send(data);
});
数据的新增, 使用骨架, 只能增加骨架的数据,
router.get('/add.html', function(req, res, next){
var user = new userModel();
user.name = "盛密红";
user.age = 67;
user.save(function(){
res.send('<h1>数据新增成功</h1>')
})
})
// 数据保存
router.get('/modify.html', function(req, res){
let id = req.query.id;
userModel.findById(id).exec(function(err, data){
data.name = '王武帝';
data.age = 100;
data.save(function(err){
if (err){
res.send('修改错误');
} else {
res.send('修改成功')
}
})
})
})
需求。 制作一个基于后端模版的新闻发布系统
功能
1 允许用户发布新闻
2 可以在首页游览到全部的最新的新闻
3 允许用户操作删除功能
4 允许用户修改新闻
数据库设计
数据库名。 News
集合名 list
文档结构。
标题。 作者 来源。 内容。 时间。 点击率
title. Author. From content. Time hits
String. String. String. String. String. Number
第一部分。环境搭建。1 搭建 express 项目
1)。创建项目。 Express -e 项目名称
2)。安装依赖。 在线 安装。 Cnpm i
手动安装。 复制node_modules. 到项目目录
3)。监听端口
在app.js 中添加端口监听代码
app.listen(80)
4). 项目搭建
node app
5). 测试项目
手动打开项目, 输入地址 localhost
2). 配置mongoose
1). 联接数据库
mongoose.connect()
var listSchem = new mongoose.Schema({
title: String,
author: String,
from: String,
content: String,
})
sudo curl -O https://fastdl.mongodb.org/osx/mongodb-osx-ssl-x86_64-4.4.2.tgz
sudo tar -zxvf mongodb-osx-ssl-x86_64-4.4.2.tgz
sudo mv mongodb-osx-x86_64-4.4.2/ mongodb
Copy the code