网络基础
URL
-
在WWW上,每一信息资源都有统一的且在网上唯一的地址,该地址就叫URL(Uniform Resource Locator,统一资源定位器),它是WWW的统一资源定位标志,就是指网络地址。
-
URL的一般语法格式为:(带方括号[]的为可选项):
- protocol :// hostname[:port] / path / ?query #fragment
- 协议 :// 主机地址[:端口号] / [路径] [?参数] [#锚点]
URL用于定位网络当中的资源,每个资源都对应着一个独一无二的URL地址。
协议
什么是HTTP
超文本传输协议,是一个基于请求与响应,无状态的,应用层的协议,常基于TCP/IP协议传输数据,互联网上应用最为广泛的一种网络协议,所有的WWW文件都必须遵守这个标准,
HTTP协议默认端口号是 80
什么是HTTPS
HTTPS 是身披 SSL外壳的 HTTP。HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包。HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性。
HTTPS协议默认端口号是 443
主机地址
IP地址
IP地址(Internet Protocol Address)是指互联网协议地址,又译为网际协议地址。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。
比如生活中的地址,表示地理上的一个位置,通过这个地址可以找到这个地理位置。
同样的,互联网中的每一台主机电脑,都有一个地址。通过这个地址可以找到这台主机电脑。
本机IP:127.0.0.1
域名
形如 www.xxx.com 这样的就叫做域名,域名需要单独购买。购买后,需要绑定IP地址进行使用。绑定IP地址后,就可以通过域名找到主机电脑了。
本机域名:localhost
DNS服务器
DNS服务器用于记录 IP地址和域名的对应关系。
前面说,域名和IP地址是绑定关系,那么某个域名绑定的IP地址是什么呢?这个对应关系就记录在DNS服务器当中。
通过DNS服务器可以解析出 一个域名对应的IP地址。
www.itcbc.com ----------------- 123.57.103.104
www.baidu.com ----------------- 23.89.134.189
端口号
所谓的端口,就好像是门牌号一样,客户端可以通过ip地址找到对应的服务器端
但是服务器端是有很多应用程序的,每个应用程序对应一个端口号,通过端口号,客户端才能真正的访问到该服务器上的应用程序。
为了对端口进行区分,将每个端口进行了编号,这就是端口号。
端口号的范围是 0 ~ 65535
客户端请求服务器的步骤
当我们在浏览器地址栏输入 “www.xxx.com/api/getbook…
- 先找到服务器
- 检测浏览器缓存有没有缓存该域名对应的IP地址。有则通过IP地址去找服务器
- 检测本地的hosts文件,是否有记录该域名对应的IP地址,有则通过IP地址去找服务器
- 通过DNS服务器解析,找到该域名对应的IP地址,然后通过IP地址去找服务器
- 进行三次握手(建立连接)
- 第一次握手是在建立连接,客户端发送连接请求报文段,把标有SYN的数据包发给服务器端即为接收端。
- 第二次握手是服务器端即接收端收到客户端的SYN的报文段,同时发送标有SYN/ACK的数据包。
- 第三次握手是客户端收到服务器端的SYN/ACK的数据包后,向服务器端发送标有ACK的数据包。
- 发送请求,传输数据。。。
- 服务器处理,并做出响应
- 浏览器接收响应结果。
- 四次挥手(作用是断开连接)
Express
express 介绍
- Express 是一个第三方模块,用于快速搭建服务器(替代http模块)
- Express 是一个基于 Node.js 平台,快速、开放、极简的 web 开发框架。同类型产品 Koa
- Express保留了http模块的基本API,使用express的时候,也能使用http的API
- 使用express的时候,仍然可以使用http模块的方法,比如 res.end()、req.url
- express还额外封装了一些新方法,能让我们更方便的搭建服务器
- express提供了中间件功能,其他很多强大的第三方模块都是基于express开发的
- Express 官网
- Express 中文文档(非官方)
- Express GitHub仓库
- 菜鸟教程
- 腾讯云开发者手册
- 百度自行搜索
安装 express
项目文件夹中,执行 npm i express。即可下载安装express。
注意:express不能安装在express文件夹中。否则安装失败。
使用Express构造Web服务器
使用Express构建Web服务器步骤:
-
加载 express 模块
-
创建 express 服务器
-
开启服务器
-
监听浏览器请求并进行处理
// 1 引入 express 第三方模块
import express from "express";
// 2 express 函数 调用 才可以返回 服务器对象
const app = express();
// 3 服务器 开启监听
// /list
// get
// 返回数组
app.get("/list", (req, res) => {
// request 请求对象
// response 响应对象
res.send({ name: "aaa" });
})
// 4 设定端口号 8899
app.listen(8899, () => {
console.log("8899 开启成功");
})
express封装的方法
express之所以能够实现web服务器的搭建,是因为其内部对核心模块http进行了封装。
封装之后,express提供了非常方便好用的方法。
比如前面用到的 app.get() 和 app.post() 就是express封装的新方法。
下面再介绍一个 res.send() 方法
- 该方法可以代替原生http模块中的 res.end 方法,而且比 res.end 方法更好用
- res.send() 用于做出响应
- 响应的内容同样不能为数字
- 如果响应的是JS对象,那么方法内部会自动将对象转成JSON格式。
- 而且会自动加Content-Type响应头
- 如果已经做出响应了,就不要再次做出响应了。
const express = require('express');
const app = express();
app.listen(3006, () => console.log('启动了'));
// 写接口
app.get('/api/test', (req, res) => {
// res.end('hello world,哈哈哈'); // 响应中文会乱码,必须自己加响应头
// res.end(JSON.stringify({ status: 0, message: '注册成功' })); // 只能响应字符串或者buffer类型
// express提供的send方法,可以解决上面的两个问题
res.send({ status: 0, message: '注册成功' }); // send方法会自动设置响应头;并且会自动把对象转成JSON字符串
});
使用 nodemon 命令运行上述代码后,即可使用 http://localhost:3000/api/test 请求接口了。
全局模块 nodemon
当服务器代码修改后,就要重新启动服务,非常麻烦。
nodemon 是一个全局模块,安装后,可以使用 nodemon 代替 node 运行js文件。
好处是,当代码保存后,nodemon 会检测文件代码是否改变了,如果改变了,就会自动重启服务器。
全局安装nodemon
npm i nodemon -g
使用
nodemon xxx.js
使用nodemon 命令代替node命令,我们就可以专心开发代码了,而不用但是服务有没有重启的问题了。
建议不要滥用nodemon,建议只在启动服务时使用nodemon。其他情况继续使用node。
写接口
写接口的目的是体会后端的接口是怎么写的。所以写最简单的接口即可。
- 创建后端接口项目文件夹,比如 code
- 下载安装所需模块 express
创建index.js
创建index.js,作用是编写后端代码,启动服务。
使用的模块为 express。
初始代码,可以去 www.expressjs.com.cn/starter/hel… 复制并修改
// 用于启动服务,并且写接口
const express = require('express')
const app = express()
// 写接口
// app.请求方式('接口地址', '带有req、res参数的处理函数');
// app.get('/api/student', (req, res) => {});
// app.post();
// app.delete();
// app.put();
app.listen(3000, () => console.log('启动了'));
只需这几行,就可以使用 nodemon index.js 启动服务了。
封装操作JSON的模块
- 准备好存储数据的 json文件(
db.json)。 - 准备好处理JSON文件的自定义模块。
准备JSON文件
真实开发中,数据一般都放在数据库中存储,作为前端程序员,大部分都不了解数据库。
所以,我们可以使用JSON文件存储数据。(使用JSON文件代替数据库,以便完成后续的开发)
创建 db.json ,文件内容如下:
[
{
"id": 1,
"bookname": "西游记",
"author": "吴承恩",
"publisher": "北京出版社"
},
{
"id": 2,
"bookname": "红楼梦",
"author": "曹雪芹",
"publisher": "上海出版社"
},
{
"id": 5,
"bookname": "水浒传",
"author": "施耐庵",
"publisher": "清华出版社"
},
{
"id": 12,
"bookname": "三国演义",
"author": "罗贯中",
"publisher": "商务出版社"
}
]
封装操作JSON文件的模块
为了方便对JSON文件中的数据进行查询,新增,修改,删除等操作。我们自己封装一个自定义模块
-
自己创建
json-parser.js文件 -
我们可以使用 then-fs 进行封装。
-
约定,每一个方法都返回Promise对象(为了方便,查询方法query可以返回查询数据)
-
后期,就可以通过 .then 或者 async和await 获取结果了。
-
这样,就可以知道Promise如何使用了。
代码如下:
const { join } = require('path');
const fs = require('then-fs');
// 拼接文件路径
const filename = join(__dirname, 'db.json');
// ------------------ 获取数据 ----------------------
async function query() {
let data = await fs.readFile(filename, 'utf-8');
return JSON.parse(data);
}
// ------------------ 添加数据 ----------------------
async function add(row) {
let res = await query();
let id = res[res.length - 1].id + 1;
row.id = id;
res.push(row);
return fs.writeFile(filename, JSON.stringify(res));
}
// ------------------ 删除数据 ----------------------
async function del(id) {
let res = await query();
let result = res.filter(item => item.id != id);
return fs.writeFile(filename, JSON.stringify(result));
}
// ------------------ 修改数据 ----------------------
async function update(row) {
let res = await query();
let index = res.findIndex(item => item.id == row.id);
res.splice(index, 1, row);
return fs.writeFile(filename, JSON.stringify(res));
}
// 导出
module.exports = { query, add, del, update };
获取图书接口
- 接口名称:/api/getbooks
- 请求方式:GET
- 请求参数:无
- 响应数据:
{ status: 0, message: '获取图书成功', data: [ { 一本书 }, { 一本书 } ] }
基本代码如下:
const { query, add, del, update } = require('./json-parser'); // 导入 处理JSON文件的模块
app.get('/api/getbooks', async (req, res) => {
let data = await query();
res.send({ status: 0, message: '获取图书成功', data });
})
接下来,可以使用客户端发送请求检测了。
添加图书接口
- 接口名称:/api/addbook
- 请求方式:POST
- 请求体:bookname (书名)、author(作者)、publisher(出版社)
- Content-Type: application/x-www-form-urlencoded
- 响应数据:
{ status: 0, message: '添加图书成功' }
基本代码如下:
// 配置,接收请求体
app.use(express.urlencoded({ extended: true })); // 接收查询字符串格式请求体
app.post('/api/addbook', async (req, res) => {
let row = req.body;
let r = await add(row);
if (r === undefined) {
res.send({ status: 0, message: '添加成功' })
}
})
接下来,可以使用客户端发送请求检测了。
修改图书接口
- 接口名称:/api/updatebook
- 请求方式:PUT
- 请求体:id(ID)、bookname (书名)、author(作者)、publisher(出版社)
- Content-Type: application/x-www-form-urlencoded
- 响应数据:
{ status: 0, message: '修改图书成功' }
所以:
app.put('/api/updatebook', async (req, res) => {
let row = req.body;
let r = await update(row);
if (r === undefined) {
res.send({ status: 0, message: '修改成功' })
}
})
接下来,可以使用客户端发送请求检测了。
删除图书接口
- 接口名称:/api/delbook
- 请求方式:DELETE
- 请求参数:id(ID)
- 响应数据:
{ status: 0, message: '删除图书成功' }
所以:
app.delete('/api/delbook', (req, res) => {
let id = req.query.id;
obj.del(id)
res.send({ status: 0, message: '删除图书成功' })
});
接下来,可以使用客户端发送请求检测了。
使用前端代码测试接口
前端发送Ajax请求,请求接口。会有跨域问题。
这里可以使用CORS方案解决跨域。
后端
-
安装 cors 模块。
npm i cors -
代码中,在所有接口之前,加载cors,并注册为中间件。
let cors = require('cors')app.use(cors())
前端
正常发送请求即可。
<script src="./axios.js"></script>
<script>
axios.get('http://localhost:3000/api/getbooks').then(result => {
console.log(result);
});
</script>