node-day01
1. 什么是nodejs
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
Node 是一个让 JavaScript 运行在服务端的开发平台,它让 JavaScript 成为与PHP、Python、Perl、Ruby 等服务端语言平起平坐的脚本语言。
2. 部署 nodejs 运行环境 (了解)
- 安装
https://nodejs.org
- 卸载
删除 c盘 的nodejs文件
删除 c盘 /users/用户名/appData/Roaming/npm
3. 前后端的概念 (了解)
项目开发流程
- 市场调研
寻找适合的人群
- 研讨会(需求分析会 )
+ 确定开发的需求
+ ui 设计原型图
+ 后台 确定好技术栈 设计数据库
+ 前端 确定好技术栈
真实开发
测试
白盒、黑盒
产品发布会 (推销产品)
产品维护
4. Nodejs 的组成部分(了解)
- JavaScript 基于浏览器
ECMAScript 核心
DOM 文档对象模型
BOM 浏览器对象模型
- NodeJS 运行在服务器环境
ECMAScript 核心
-
全局成员
setTimeout console.log
-
系统模块
node安装的时候已经装在我们本地
5. es6语法学习 (重点)
5.1 let const
没有变量提升
具有块级作用域
const 定义之后一定能要赋值,并且之后不能重新赋值
5.2 解构赋值
- 解构数组
// var [a, , , d] = [1, 2, 3, 4]
// console.log(a, d)
- 解构对象
var obj = {
name: 'fly',
age: 18,
sex: '男'
}
// 以前写法
// var name = obj.name
// var age = obj.age
// var sex = obj.sex
//对象解构赋值 如果需要改变变量名 可以使用 要解构的属性:重新定义的变量名
var { name:name123, age, sex } = obj
console.log(name123, age, sex)
// 练习1 对象中有数组
const result = {
status: 0,
message: [
{
name: 'fly',
age: 18
}
]
}
const { status, message } = result
const { name } = message[0]
console.log(status, name)
// 练习2 对象中有对象
const result = {
data: {
status: 0,
message: [
{
name: 'fly',
age: 18
}
]
}
}
const { data, data: { status } } = result
console.log(data, status)
5.3 字符串的拓展
- startsWith 和 endsWith
startsWith 是否以xxx 开头 如果是 返回true
endsWith 是否以xxx 结尾 如果是 返回true
let str = 'flsfjlsfjlsfj'
console.log(str.endsWith('j'))
- padStart 和 padEnd
padStart 给某个字符串之前拼接
padEnd 给某个字符串之后拼接
let str = 'fly'
// 参数1 length 拼接之后字符串的总长度
// 参数2 str 以什么字符串进行拼接
console.log(str.padStart(5, '0').padEnd(7, '0'))
- 模板字符串 ``
${} 只能在 `` 中使用
var addStr = '-------'
var newstr = `fly${addStr}sky`
5.4 参数默认值 + 解构赋值
- 函数中传统默认值和es6默认值对比
// es5
function show(n){
// 防止用户没有传入参数的时候 number 输出 undefined
var number = n || 0
console.log(number)
}
show()
// es6
function show(n = 0){
console.log(number)
}
show()
2. 解构赋值 + 参数默认值
```js
// es5
function show(o,y){
var n = y || 0
console.log(o.x,n)
}
show({x:1})
// es6
function show({x,y = 0}){
console.log(x,y)
}
show({x:1})
5.5 rest参数和字符串扩展
// 在函数定义的时候 使用的 ...obj 叫做rest参数
function show(...rest) { // 当前的rest 是一个数组
console.log(rest)
let result = 0
// for (var i = 0; i < arguments.length; i++) {
// result += arguments[i]
// }
rest.forEach(function (item) {
result += item
})
console.log(result)
}
let arr = [1, 2, 3, 4, 5, 6]
// 在函数调用的时候 使用的 ...obj 叫做字符串的拓展
show(...arr) // 把数组展开
5.6 箭头函数
// 标准写法
var show = (item) => {
return item
}
console.log(show(1))
// 最简化的写法
var show = item => item
console.log(show(1))
var show = (x, y) => x + y
console.log(show(1, 2))
var obj = {
name: 'fly',
show: function () {
// console.log(this)
// var that = this
// 箭头函数的this 永远指向他之外的this
setTimeout(() => {
console.log(this.name)
})
}
}
obj.show()
5.7 继承
// es5 没有类的概念 构造函数 + 原型
// 组合继承 构造函数继承 + 原型继承
// 1. 继承属性
// 2. 继承方法
function Person(name, age) {
//this指向实例化的对象也就是 person
this.name = name
this.age = age
}
Person.prototype.say = function () {
console.log(this.name)
}
function LongXia(name, age) {
console.log(this) // this 指向了 longxia
// 对象冒充 主要是为了继承父类的属性
Person.call(this, name, age) // this 指向了 person
}
// 子类的原型赋值给 父类的实例化
LongXia.prototype = new Person()
var longxia = new LongXia('龙虾', 666)
console.log(longxia.name)
longxia.say()
// es6 继承
class Person {
// 构造函数 constructor 固定的
constructor(name, age) {
// // this指向实例化的对象也就是 person
this.name = name
this.age = age
}
// 原型上的方法
say() {
console.log(this.name)
}
}
class LongXia extends Person {
// 构造函数
constructor(name, age, job) {
// 对象冒充改变this的指向
// Person.call(this.name,age)
super(name, age)
this.job = job
}
// 原型上的方法
say() {
console.log(this.name)
}
}
const longxia = new LongXia('小龙', 18, 'IT')
console.log(longxia.name) // name 来至于父类
console.log(longxia.job) // job 自身的属性
longxia.say() // say 来至于父类的方法
5.8 对象中的简化写法
var name = 'fly'
var age = 18
var show = function () {
}
// es5
var obj = {
name: name,
age: age,
show: show,
say: function(){
}
}
// es6
var obj = {
name,
age,
show,
say() {
}
}
console.log(obj)
node-day02
1. fs模块 (了解)
1.1 fs.readFile(path[,options],callback)
path 读取路径
options 可选参数 默认为 null
callback 读取文件的回调函数 err,data
示例
// 1.0 引入fs模块
const fs = require('fs')
// 2.0 读取文件
fs.readFile('./files/1.txt','utf-8',(err,data)=>{
if(err)return console.log(err.message)
console.log(data)
})
1.2 fs.witerFile(path,data[,options],callback)
path 读取路径
data 要写入的数据
options 可选参数 默认为 utf-8
callback 读取文件的回调函数 err
示例
// 1.0 引入fs模块
const fs = require('fs')
// 2.0 读取文件
fs.witerFile('./files/2.txt','ssssss',(err)=>{
if(err)return console.log(err.message)
console.log('写入成功')
})
// ps: 写入的文件会覆盖之前的内容
1.3 拷贝文件
- 传统方式
// 复制思路
// 1.0 先使用 readFile 读取某个文件
// 2.0 再使用 writeFile 把读取的内容写入到另一个文件中
fs.readFile('./file/2.txt', 'utf-8', (err, buf) => {
// console.log(err)
if (err) return console.log(err.message)
// 2. 把读取的内容写入拷贝的文件
fs.writeFile('./file/2-copy.txt', buf, err => {
if (err) return console.log(err.message)
console.log('写入成功')
})
})
- fs.copyFile(src, dest[, flags], callback)
src 拷贝的文件源
dest 拷贝到那个文件
flags 可选 是否拷贝
callback 拷贝的回调函数 err
// node 需要时 v8.5.0 以上的
const fs = require("fs");
// 默认情况下,destination.txt 将创建或覆盖
fs.copyFile("./files/1.txt", "./files/1 - copy.txt", err => {
if (err) throw err;
console.log("拷贝成功");
});
1.4 fs.appendFile(path, data[, options], callback)
path 读取路径
data 要写入的数据
options 可选参数 默认为 utf-8
callback 读取文件的回调函数 err
// 追加
fs.appendFile('message.txt', 'data to append', (err) => {
if (err) throw err;
console.log('The "data to append" was appended to file!');
});
2. path模块 (了解)
path.join(path)
__dirname + '/files/1.txt'
const path = require('path')
path.join(__dirname,'./files/1.txt')
ps: 以后涉及到路径拼接的时候 尽量使用path模块
3. __dirname 、__filename 路径(了解)
-
__dirname
/Users/fly/Desktop
__filename
/Users/fly/Desktop/001.js
4. 单线程和多线程 (了解)
https://blog.csdn.net/hr10230322/article/details/78642898
5. nodejs的异步同步 (重点)
异步不会阻塞后面的代码
同步会阻塞后面的代码
ps:一条线程先执行同步的代码后执行异步的代码,nodejs中推荐使用异步操作
https://blog.csdn.net/qq_21033663/article/details/51564786
6. 模块化概念理解(重点)
6.1 移动支付
- 谁实现了移动支付
-
微信支付
微信扫一扫 引入
微信二维码 暴露
-
支付宝支付
支付宝扫一扫 引入
支付宝二维码 暴露
6.2 模块化
- 什么叫模块化
在一个js文件中引入另一个js文件
- 如何实现模块化
-
前端模块化
require.js AMD
sea.js CMD
-
后端模块化
common.js
- common如何去引入 和暴露
require 引入
exports global 暴露
module 标识符 是一个对象
ps: common js 就是一套后端的模块化规范,nodejs是commonjs的实现
node-day03
1. 模块化(重点)
1.1 什么是模块化 (面试)
在一个js文件中,引入另一个js文件
1.2 nodejs为什么需要模块化
nodejs 没有页面,只有js文件,如果不能相互引入,nodejs就没有意义
ps: nodejs 是 commonJS的实现
1.3 如何实现模块化
-
前端方式 (了解)
require.js
sea.js
-
后端方式
commonJS
大一统的es6 模块化
2. commonjs 的特性规范 (重点)
引入 require
暴露 exports module.expors global
-
对象 module(是一个标识符)
const m1 = module.require('./m1.js') // 导入自己的m1.js模块 module 是可以省略的
global (全局变量、基本不用)
global 只能访问 global 暴露的数据 ,不能访问 export 暴露的数据
export 和 module.export 的区别
// 暴露的方式 2 种
export.a = 1
module.export.b = 2
// 指向相同的对象
export.a = 1
module.export= {
b: 2
}
//指向不同的对象,并以module.export 的对象为主 ,以后为了避免使用错误,推荐使用 module.export = {} 暴露数据
3. 模块分类 (了解)
- 系统核心模块
require('fs')
fs 存在node安装的文件夹中
- 第三方模块
require('jquery')
jquery 存放在自己下载的项目的根目录下面的node_modules
- 自定义模块
- require(相对路径)
4. 包 (了解)
4.1 什么是包
把多个模块结合在一起,放在一个文件夹中,这个文件夹就是包
4.2 包的规范
-
package.json
name 包的名称
version 版本号
main 包的入口路径
lib / src 存放源码
dist 存放外界使用的
test 测试文件
doc 文档
5. 包的管理工具 npm、yarn 、cnpm(重点)
5.1 npm切换淘宝镜像
- 直接设置 淘宝镜像
npm config set registry https:*//registry.npm.taobao.org*
npm config get registry
- 使用nrm 设置 镜像源比较多选择比较强
npm install nrm -g
nrm -V
nrm use taobao 把镜像切换到taobao
nrm ls | list 查看切换到那个镜像源
5.2 安装yarn (最快的)
npm install yarn -g
yarn -v
5.3 cnpm (这个镜像源只有淘宝的) 中国版的 npm (装的包比较恶心不建议使用)
npm install -g cnpm --registry=https://registry.npm.taobao.org
- 三者常用命令
npm install jquery -S
npm uninstall jquery -S
npm i
cnpm install jquery -S
cnpm uninstall jquery -S
cnpm i
yarn add jquery -S
yarn remove jquery -S
yarn
6. 包的安装
6.1 全局包 (工具类的包)
- c:/users/自己的用户/AppData/Roaming/npm/node_modules
6.2 本地包
npm init -y (没有package.json文件的时候才需要,只需要初始化一次即可)
-S 全写 --save 项目打包上线的时候需要 比如 jquery bootstrap
-D 全写 --save-dev 开发环境需要 比如 less上线的时候不需要使用
ps: 系统的包和第三方包在引入的时候不需要加上 node_modules
-
第三方包的查找规则
先在node_modules 中查找相应的包名
再项目的根目录查找package.json
再查找main属性对应的文件
试运行该文件
7. 使用nodejs 搭建一个web服务器 (了解)
// 1. 引入http
const http = require('http')
// 2. 创建服务
const server = http.createServer()
let count = 0
// 3. 监听请求地址
server.on('request', function (req, res) { // 3.1 监听请求地址
// 3.2 处理
console.log('hello node' + count++)
// 3.3 响应
res.end('hello node')
})
// 4. 监听端口
// 参数1 端口号
// 参数2 ip 可选
// 参数3 callback
server.listen(3000, '192.168.15.21', function () {
console.log('后台服务开启在了 http://192.168.15.21:3000')
})
node-day04
1. mac系统和window系统 apache 服务 (了解)
1.1 window
phpstudy apache服务器 mysql服务器
wamp apache服务器 mysql服务器
1.2 mac
- mamp apache服务器 mysql服务器
2. 协议、ip、域名、端口、dns服务器 (了解)
协议 https http
ip 192.169.1.1
域名 www.baidu.com
dns服务器 处理 ip 和域名 的对应关系
端口 可以让一台服务根据端口提供不同的服务
3. node服务器 (了解)
3.1 原生方式
// 1.0 引入http模块
const http = require('http')
// 2.0 创建node服务
const server = http.createServer()
// 3.0 监听路径请求
server.on('request',(req,res)=>{
// 处理逻辑
console.log(1)
res.end('hello nodejs')
})
// 4.0 给服务设置端口号
// 参数1 端口号
// 参数2 ip 可选
// 参数3 callback 回调函数
server.listen(3000,()=>{
console.log('http://127.0.0.1:3000')
})
// 通信模型
// 请求--> 处理 --> 响应
4. 静态资源服务器 (了解)
const http = require('http')
const fs = require('fs')
const path = require('path')
const server = http.createServer()
server.on('request', (req, res) => {
// 拿到请求的类型
const method = req.method.toLowerCase()
// 拿到请求的地址
const url = req.url
// 因为 我们浏览器请求的 URL地址,已经和 服务器上,文件的物理路径,对应上了;
// 静态的资源都是 什么请求方式 ? get
readStaticFile(res, url)
})
server.listen(3000, () => {
console.log('http://127.0.0.1:3000')
})
// 静态资源托管 原生方式 express 框架
function readStaticFile(res, url) {
fs.readFile(path.join(__dirname, url), (err, data) => {
if (err) return res.end('404')
res.end(data)
})
}
5. node结合art-template (重点)
5.1 前端 art-template
使用script引入art-template
var html = template(id,obj)
$('xxx').html(html)
5.2 后端 art-template
- 安装 art-template 包
yarn add art-template -S
- 引入art-template
const template = require('art-template')
- 使用 art-template 绑定页面和数据
var html = template(abspath,obj) // abspath 是页面所在的绝对路径
- 响应给前端
res.end(html)
6. 服务端渲染(SSR)和客户端渲染的对比 (拓展)
http://www.cnblogs.com/sunqq/p/8257243.html
node-day05
1. express
1.1 express的基本使用 (了解)
装包
yarn add express -S
// 1. 导入 express 模块
const express = require('express')
// 2. 创建服务器
const app = express()
// app.get 表示,只监听 get 类型的请求
// app.post 表示,只监听 post 类型的请求
// app.all 表示,监听所有类型的请求
app.get('/', function (req, res) {
// 这里,我们使用 的 res.end 是原生 Node 提供的 API
res.send('试试就试试123')
})
// /index.html
// /movie.html
app.listen(4000, () => {
console.log('express server running at http://127.0.0.1:4000')
})
1.2 静态资源托管
原生静态资源托管
const http = require('http')
const fs = require('fs')
const path = require('path')
const mime = require('mime')
const server = http.createServer()
server.on('request', (req, res) => {
// 拿到请求的类型
const method = req.method.toLowerCase()
// 拿到请求的地址
const url = req.url
// 因为 我们浏览器请求的 URL地址,已经和 服务器上,文件的物理路径,对应上了;
// 静态的资源都是 什么请求方式 ? get
readStaticFile(res, url)
})
server.listen(3000, () => {
console.log('http://127.0.0.1:3000')
})
// 封装静态资源托管函数
function readStaticFile(res, url) {
fs.readFile(path.join(__dirname, url), (err, data) => {
if (err) return res.end('404')
res.end(data)
})
}
express静态资源托管 (了解)
const express = require('express')
const path = require('path')
const app = express()
// 使用 express.static 来托管 views 目录
// 第一个assets 是标识符,用于服务器路径的拼接 http://127.0.0.1:3000/assets
// 第二个assets 是文件夹,指定需要托管的静态资源文件
app.use('/assets',express.static(path.join(__dirname,'./assets')))
// 没有加标识符的时候 127.0.0.1:3000/style.css
// 加了标识符之后 127.0.0.1:3000/assets/style.css
app.use(express.static(path.join(__dirname,'./views'))) // 使用express 托管的文件夹不能再使用到 url 地址中
app.listen(3000, function () {
console.log('App listening on port 3000!');
});
2. nodemon工具安装 (可以自动刷新服务)
npm install nodemon -g
-
nodemon 要运行的js文件
node app.js 改成 nodemon app.js
3. 服务器、域名(拓展)
3.1 云服务器供应商
阿里云服务器
腾讯云
3.2 部署服务器准备
- 购物云服务
阿里云
腾讯云
都是需要购买备案
- 购买域名
万网
腾讯
也是需要备案
- dns解析
把域名和自己的服务器的ip绑定在一起
-
ps: 这些东西都是谁来处理的 ?
运维
后台
前端 (告辞)
4. 模板引擎使用 (重点)
4.1 art-template
// 1. 引入已经安装好的express
const express = require('express')
const path = require('path')
// 引入安装好的art-template
const template = require('art-template')
// 2. 创建服务
const app = express()
const obj = {
name: 'fly',
age: 18
}
app.get('/', (req, res) => {
let htmlStr = template(path.join(__dirname, './views/index.html'), obj)
res.end(htmlStr)
})
// 4. 监听端口
app.listen(4000, function () {
console.log('express server running at http://127.0.0.1:4000')
})
4.2 ejs (是nodejs兼容性比较好的)
-
使用.ejs后缀的文件作为模板引擎
// 1. 引入已经安装好的express const express = require('express') const path = require('path') // 2. 创建服务 const app = express() // 设置使用的模板引擎类型 ejs app.set('view engine', 'ejs') // 设置模板的位置 app.set('views', path.join(__dirname, './views')) const obj = { name: 'fly', age: 18 } app.get('/', (req, res) => { res.render('index.ejs',obj) }) // 4. 监听端口 app.listen(5000, function () { console.log('express server running at http://127.0.0.1:5000') })
-
使用.html后缀的文件作为模板引擎
// 1. 引入已经安装好的express const express = require('express') const path = require('path') const ejs = require('ejs').__express // 2. 创建服务 const app = express() // 设置使用的模板引擎类型 html app.set('view engine', 'html') // 设置模板类型 html页面必须放在views 文件夹中 app.engine('html',ejs) const obj = { name: 'fly', age: 18 } app.get('/', (req, res) => { res.render('index.html',obj) }) // 4. 监听端口 app.listen(5000, function () { console.log('express server running at http://127.0.0.1:5000') })
5. res常用的函数 (了解)
res.end() 原生
res.json() 返回一个对象,一般是写接口的时候使用
res.redirect() 原生
res.render() 使用类似于ejs的时候使用
res.send() 中文乱码
res.sendFile 托管少量的静态资源,以后很少使用
6. 路由 (面试)
路由是一种对应关系
6.1 后端路由
前端的请求url 和 处理url的函数的对应关系,就叫后端路由
6.2 前端路由 (vue、angular、react)
6.3 模块化开发的优点
模块化并不能减少我们的代码量,但是可以使得我们的页面更加清晰,也方便后期的维护
6.4 express 路由使用
- 先引入express
const express = require('express')
- 使用exprss.Router() 创建路由
const router = express.Router()
- 把处理的对应关系挂载router上
router.get('/',callbcak)
- 在app上注册router
app.use(router)
node-day06
1. 中间件 (了解)
1.1 什么是中间件
中间件是一个处理函数 这个函数具有三个参数 req ,res,next
中间件按照先后循序执行
下一个中间件想拿到上一个中间年的值,上一个中间件必须调用next
所有的中间件中 req res 都是共享的
中间使用 use 调用
中间件在所有的请求之前调用
所有的中间件一定要在请求之前执行
1.2 中间件的定义
function middle(req,res,next){
next()
}
app.use(middle)
1.3 中间件分类 (记忆)
- 应用级中间件: 挂载在app上的
app.use((req,res,next)=>{
})
- 路由级中间件: 挂载在router上的
router.get((req,res,next)=>{
})
- 错误处理中间件: 必须带有err,req,res,next
app.use((err,req,res,next)=>{
})
- 内置中间件: express.static() 现在唯一一个内置的中间件
1.4 第三方中间件
body-parser
express-session
...
2. 模块查找规则 (了解)
2.1 核心模块
默认先从缓存中查找
在本地引入查找,找到了之后再缓存起来
2.2 自定义模块
默认先从缓存中查找
-
查找的循序
index --> index.js --> index.json --> 二进制文件
2.3 第三方模块
默认先从缓存中查找
-
查找的循序
自定义包
先查找文件夹 --> package.json --> main --> 指定的文件
第三方模块
node_modules --> 查找文件夹 --> package.json --> main(试图运行index.js) --> 指定的文件
node_modules --> 查找文件夹 --> index.js
3. NodeJS中使用mysql (了解)
3.1 基本使用
var mysql = require('mysql');
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root',
database: 'mydb_12_9'
});
var sql = 'select * from users where isdel = 0'
connection.query(sql, function (error, results, fields) {
if (error) throw error;
console.log(results)
});
3.2使用mysql进行CRUD
- 查询
var sql = 'select * from users where isdel = 0'
connection.query(sql, function (error, results, fields) {
if (error) throw error;
console.log(results)
});
- 添加
var obj = {
username: '666',
age: 18,
gender: '女'
}
var sql = 'insert into users set ?'
connection.query(sql, obj, function (error, results, fields) {
if (error) throw error;
console.log(results)
});
- 更新
var obj = {
id: 1,
username: '999',
age: 18,
gender: '女'
}
var sql = 'update users set ? where id =?'
connection.query(sql, [obj, obj.id], function (error, results, fields) {
if (error) throw error;
console.log(results)
});
- 删除
var sql = 'delete users set isdel = 1 where id =?'
connection.query(sql, 7, function (error, results, fields) {
if (error) throw error;
console.log(results)
});
- 软删除
var sql = 'update users set isdel = 1 where id =?' // 第2个id 一般是通过请求路径传递回来的
connection.query(sql, 7, function (error, results, fields) {
if (error) throw error;
console.log(results)
});
4. 参数传递的常用方式
4.1 get请求
-
query
http://127.0.0.1:3000/?name=fly&age=18 router.get('/',(req,res)=>{ console.log(req.query.name) console.log(req.query.age) })
-
params
http://127.0.0.1:3000/fly/18 router.get('/:name/:age',(req,res)=>{ console.log(req.params.name) console.log(req.params.age) })
4.2 post 请求
yarn add body-parser -S
const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({extented:false}))
可以在任意的路由中使用 req.body 获取解析后的参数