三阶段需要使用到的知识点你以前学过的- 数组操作
- push/pop/shift/unshift,分别在数组的开头或者结尾插入或者删除一个元素
- splice,数组替换。三个参数,参数一表示位置、参数二表示数量、参数三表示用来替换的内容(剩余的参数);如果不给第三个参数表示从指定位置开始,删除指定数量的数据
- find,从数组中查找符合条件的第一个记录。find接受一个function作为参数,只要回调函数返回true那么表示匹配成功
- findIndex,从数组中查找符合条件的记录的索引。如果不存在返回-1
- indexOf,获取索引。如果不存在返回-1
- filter,过滤。查找数组中符合条件的数据,只要回调函数返回true表示符合条件
- every,判断数据中的每一项是否都符合条件。如果是返回true否则返回false
- sort,排序
- map,循环数组的每一项,生成一个新的数组对象。新数组的长度和原数组一样。新数组的每一项是原数组循环时每一项的返回值
- forEach,循环数组的每一项
- reduce,聚合操作。把数组进行计算之后生成一个计算结果,最常见的一个操作就是求和
- 对象操作
- 深拷贝和浅拷贝
- 深拷贝是逐层拷贝对象的每一级,JSON.parse(JSON.stringify(obj))
- 浅拷贝是只拷贝对象的第一级
- 删除一个属性
- delete,需要注意delete是js的关键字,在定义变量和function的时候不能使用
- 获取所有的属性名
- for in
- Object.keys
- Promise
- Promise是用来解决异步回调地狱问题的。他有三个状态:pending、fulfilled、rejected,这三个状态是不可逆的。then的时候我们可以获取成功时候的回调函数的返回值
- const p1 = new Promise((reslove, rejected)=>{
///
})
p1.then(res=>{
///
}).catch.... - .all,表示Promise对象组成的数组中的所有Promise都执行成功之后触发,返回的结果为每一个Promise成功的结果组成的数组
- .race,表示只要有一个完成就结束了
- async/await
- es6
- const/let
- const定义常量,就是不再改变的数据
- let用来定义临时变量
- 箭头函数
- 就是箭头函数,没有this指向,没有原型。不能用来做继承
- 如果只有一行,那么不需要写return
- 解构赋值
- 扩展运算符
- ... // 扩展运算符
- 模版字符串
- var id = 1
// var str = `http://localhost:1337/api/v1/products/${id}`
var str = 'http://localhost:1337/api/v1/products/' id - 模块
- export
import
require/module.exports
// amd/cmd
nodejs基础http://nodejs.cn/api/ api文档地址(这个是node的api文档地址,需要的时候可以用来查看,千万不要花时间背api接口文档)
运行环境:nodejs是一个运行环境,js是一门开发语言。运行环境是运行开发语言的一个平台。我们现在已经学习过的一个运行环境是浏览器
- npm包管理工具(重点)【本周重点内容一】
- npm init # 创建一个package.json文件
npm install xx # install可以简写为i
npm i xx # 安装一个第三方模块,xx表示模块名字
npm uninstall xx # 卸载模块
npm init生成的package.json文件中有一个scripts节点,它表示我们可以直接运行的npm命令,它配置的属性名可以直接通过npm run执行,但是需要注意的是start命令是唯一一个不需要run就能执行的命令
npm设置nodejs安装好之后需要设置npm的镜像地址为淘宝
npm config set registry https://registry.npm.taobao.org
node中运行代码,直接通过在终端执行命令node xx.js
- 基础模块
- nodejs自定义模块
- 第三方模块
- axios
- 是一个发起网络请求的插件,可以在node和浏览器环境中同时使用。是我们以后使用的发起网络请求的一个主要的插件
- http://github.com/axios/axios 官网地址
- axios是一个用来发起网络请求的插件,可以用来代替jQuery。他可以在浏览器和node环境中同时使用,会自动判断当前的运行环境。axios是目前使用最广方的一个网络请求插件,返回的是一个Promise对象
- axios.get(url, config)
- axios.post(url, data, config)
- axios.put(url, data, config)
- axios.delete(url, config)
- 其中的参数:
- url表示请求地址
- data表示请求体中传递的数据
- config表示配置信息,就是我们自己定义的一些信息
- 最常见的就是请求头headers
- moment
- 日期格式化、日期处理插件
- http://momentjs.cn/
- lodash(一定一定要知道的,以后你工作之后使用最多的一个插件)
- https://www.lodashjs.com/
- cheerio
- 是一个字符串解析插件,可以用来解析html标签之类的富文本内容。用来做数据抓取
代码封装需要遵循一个原则:高内聚低耦合
Markdown语法# 一级标题
## 二级标题
### 三级标题
- 无序列表
1. 有序列表
```js
// 代码块
function demo() {}
```
> 引用部分内容
[百度](http://www.baidu.com)
![](http://oss.penkuoer.com/uPic/ss.jpeg)
插件推荐
Bootstrap 3 Snippets
Chinese (Simplified) Language Pack
Bracket Pair Colorizer
Code Spell Checker
Document This
ES7 React/Redux/React-Native/JS snippets
ESLint
Git History
GitLens
Guides
indent-rainbow
jQuery Code Snippets
Vetur
vscode-icons
Live Server
Prettier - Code formatter
Path Intellisense
express
https://www.expressjs.com.cn/
- 什么是express
- 是一个web开发框架,可以使用nodejs做web项目开发。
- 基础使用
- npm i express # 安装const express = require('express')
const app = express()
// 参数一 表示请求的地址
// 参数二 表示访问这个地址的时候的处理函数
// req request,请求。客户端发起请求时传递的内容
// res response,响应。服务器返回给客户端的内容
app.get('/', (req, res) => {
res.send('Hello World!') // 返回一个字符串
})
// 监听所有向我当前服务器3000端口发起的请求
app.listen(3000, ()=> {
console.log('server is running on 3000')
}) - 路由
- 分文件写代码,分模块开发
- 脚手架创建项目
- npx express-generator shop-app -e # shop-app是项目名字 -e表示使用ejs模版引擎
cd shop-app # 进入目录
npm i # 安装依赖
npm start # 启动 - ejs模版引擎
- 模版引擎的作用是代替字符串拼接,以后工作了可能需要做的一个事情叫套程序,就是使用模版语法写页面
- 就三个语法
- <% 中间的是js表达式 %>
<%= js表达式,输出在页面的内容 %>
<%- js表达式,输出在页面的富文本内容 %> - SSR和BSR
- SSR:Server Side Render,服务器端渲染。所有的网页结构和数据都在服务器端生成,客户端只负责展示页面效果
- B(C)SR: Browser(Client) Side Render,浏览器(客户端)渲染。客户端先请求一个基础的页面结构,然后加载完成之后,在通过ajax等网络请求获取数据,获取数据之后在客户端上拼接显示页面内容
- 服务器端渲染,所有的工作都是在服务器上进行的,服务器的压力会变大
- 客户端渲染,有一部分工作会分配个客户端进行,会减小服务器的压力,但是需要多次发请求,会增加网络压力
- 请求报文(重点,一定要会的)【本周重点内容二】
- 请求行
- 请求方式 路径 协议版本号
- 请求头
- 其他信息
- Content-Type表示请求体中数据的格式
- userAgent 用户代理,就是用户客户端使用的软件版本信息
- 自定义数据:token
- cookie
- 请求体
- POST或者PUT请求传递数据的地方
- 花瓶,抓包工具 https://www.charlesproxy.com/
- get请求报文
- GET /api/v1/books HTTP/1.1
Host: 192.168.1.5:3000
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7,zh-TW;q=0.6
If-None-Match: W/"14d9-9tcIwvTBahRFkViSxJmi0i1zdME"
Connection: keep-alive - post
- POST /api/v2/books HTTP/1.1
Host: 192.168.1.5:3000
Content-Length: 55
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Content-Type: application/json;charset=UTF-8
Origin: http://192.168.1.5:3000
Referer: http://192.168.1.5:3000/books.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7,zh-TW;q=0.6
Connection: keep-alive
{"title":"从你的全世界路过","id":1629267408424}POST /api/v2/books HTTP/1.1
Host: 192.168.1.5:3000
Content-Length: 41
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://192.168.1.5:3000
Referer: http://192.168.1.5:3000/books.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7,zh-TW;q=0.6
Connection: keep-alive
title=沙丘&id=1629267878573 - Content-Type:标识了我们请求体中传递的数据的格式,常见的有三种json、url编码,formData
- json和url编码用来传递表单数据
- formDate用来做文件上传
- axios发送post请求的时候默认传递的是json数据,jQuery发起请求的时候默认传递的是url编码的数据
- get和post请求的区别?
- get请求是用来取数据的,post请求是用来新增数据的
- get请求相对于post请求不安全
- get请求传递的数据量小,post请求传递的数据是不可见的在请求体中的。post请求传递的数据量稍微大一些。post请求传递的数据量大小由服务器端决定
- get请求传递的参数在url中,因为url地址由长度限制,所有get请求没有办法传递大量数据
mongodb为了让我们的数据能够永久的进行存储,我们需要使用到数据持久化技术。数据持久化就是把数据长期的存储起来,哪怕服务器重启了数据还在。常见技术有:存文件或者数据库
数据库又叫数据库系统,是我们在开发中做数据持久化的一种技术。数据库有自己的开发语言,叫sql(结构化查询语句)。目前市面上常用的数据库有:mysql,pgsql,oracle,sql server,mongodb,sqlite等。
mysql和pgsql是目前使用比较多的开源数据库,pgsql常用在gis系统中,因为其内置的有坐标和位置计算函数
oracle是目前使用最广泛的企业级数据库
mongodb是目前使用比较多的一款nosql数据库
sqlite是文件数据库,目前在移动端app开发的时候使用比较广泛
- 安装
- windows
- 最简单,下载安装包。双击,下一步、下一步、下一步、完成。没了
- https://www.mongodb.com/try/download/community 打开这个地址直接下载安装包
- 需要格外注意,这个钩去掉。
- 当你安装好之后。直接在自己的电脑中查看系统服务,里面会有一个mongodb的服务,它是自动运行的
- mac
- mac安装二进制包文件的时候使用brew brew brew(重要的事情说三遍),一定要用brew
- brew是mac中的一个软件包管理工具,用来安装一些开发软件和环境的
- https://brew.sh/ 官网,进行安装brew
- https://github.com/mongodb/homebrew-brew 安装mongodb
- brew tap mongodb/brew # 配置brew包环境
brew install mongodb-community # 安装mongodb
brew services start mongodb-community # 启动系统服务 - 第三方图形界面工具
- 数据库是没有界面的。我们可以使用一些GUI图形界面软件操作数据库,navicat premium。它可以用来连接各个数据库
- 这个软件你可以不安装,因为你以后用到的可能性很低。但是需要你知道
- mongoose插件
- http://www.mongoosejs.net/
- nodejs中操作mongodb数据库使用这个插件mongoose,他可以让我们使用js代码直接操作数据库,不需要学习数据库语法
- npm i mongoose # 安装插件APIsave 保存
findById 根据id查找一个
findOne 根据条件查找一个
find 根据条件查找多个
findByIdAndUpdate 根据id查找一个并修改
findByIdAndRemove 根据id查找一个并删除
count 统计数量
insertMany 插入多个
restful风格的api- 概念
- https://www.ruanyifeng.com/blog/2011/09/restful.html
- 他是一个写api接口的规范。目前很多公司在做的时候都参考这个规范。restful是当年一个大学教授在自己的博士论文中提出的一种api风格。建议使用资源的复数形式表示api的名字,在名字定义的时候不要出现动词,使用不同的请求方式来决定做什么处理
- get,取数据
- post,新增
- put,修改
- delete,删除
- 实践
- 服务器端接口代码
- https://github.com/btc022003/honey-home 完整的社区类项目,包含管理后台
- https://github.com/btc022003/cat-shop-server-public 商城版的接口,需要mongodb数据库
- https://github.com/Binaryify/NeteaseCloudMusicApi 一套基于nodejs实现的网易云的接口,我自己部署了一套外网地址https://net-music.penkuoer.com/
- 文件上传
- 调用服务器的文件上传接口,把文件上传给服务器。服务器收到文件之后,返回一个可以访问的路径(web路径),客户端在提交表单信息的时候把文件路径传递给服务器接口
- 最终结果是:数据库中存储的是一个文件的路径,文件是存在硬盘上的
- multer插件
- npm i multer
- 图片上传的客户端代码,需要一定会的【本周重点内容三】
- axios版
- <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>文件上传</title>
</head>
<body>
<h1>文件上传</h1>
<img
style="max-width: 100px; max-height: 100px"
src="/images/upload.png"
alt=""
onclick="selectOneFile()"
/>
<input
onchange="fileSelected(event)"
type="file"
style="display: none"
id="iptFile"
/>
<script src="https://cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.min.js"></script>
<script>
const file = document.querySelector('#iptFile');
function selectOneFile() {
file.click();
}
function fileSelected(e) {
// console.log(e.target.files);
const formData = new FormData(); // FormData是用来传递一个FormData数据的
formData.append('file', e.target.files[0]);
axios.post('/api/v1/common/file_upload', formData).then((res) => {
console.log(res);
document.querySelector('img').src = res.data.data;
});
}
</script>
</body>
</html> - jQuery版
- <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>文件上传</title>
</head>
<body>
<h1>文件上传</h1>
<img
style="max-width: 100px; max-height: 100px"
src="/images/upload.png"
alt=""
onclick="selectOneFile()"
/>
<input
onchange="fileSelected(event)"
type="file"
style="display: none"
id="iptFile"
/>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script>
const file = document.querySelector('#iptFile');
function selectOneFile() {
file.click();
}
function fileSelected(e) {
// console.log(e.target.files);
const formData = new FormData(); // FormData是用来传递一个FormData数据的
formData.append('file', e.target.files[0]);
$.ajax({
url: '/api/v1/common/file_upload',
contentType: false, // 不设置请求头中的contentType,会自动的根据数据格式进行处理
processData: false, // 不进行数据的序列化,使用数据的原有格式
type: 'POST',
data: formData,
success(res) {
console.log(res);
$('img').attr('src', res.data);
},
});
}
</script>
</body>
</html>
socket通信- 实时获取数据和应用场景以及解决方案【重点内容四】
- 轮询,客户端定义一个计数器,不停的向服务器发送请求,来获取最新的数据
- socket,长链接,客户端和服务器建立一个连接之后,服务器端有最新的数据了,那么会主动的推送给客户端
- socket.io
- npm i socket.io
服务器部署插件https://pm2.keymetrics.io/
pm2,守护进程。可以让我们启动一个nodejs项目,在后台运行。不需要一直开着命令窗口
npm i pm2 -g # 全局安装
pm2 start xx.js --name aaa # 启动文件
pm2 ls # 列出所有正在运行的项目
pm2 del xx # 删除
pm2 stop xx # 停止
pm2 restart xx # 重启