node.js入门+快速复习

  • shift + 右键 + 点击打开PowerShell打开终端自动定位到打开路径

Nodejs

安装apache

用于php创建服务器了解即可

  • 下载–>解压
  • Apache/conf/httpd.conf中的Define SRVROOT "D:\Apache\Apache24"改为Define SRVROOT "Apache24的完全路径"
  • httpd -k install -n Apache2.4 #-n后面表示自定义访问名称
  • bin目录下管理员启动cmd
    • httpd -k start启动
    • httpd -k stop关闭
    • httpd.exe启动
    • ctrl+c关闭
  • 直接双击httpd.exe程序启动
  • 关闭httpd.exe程序关闭
  • 浏览器输入localhost访问

终端命令

  • 切换路径cd
  • 执行js文件node 文件名
  • 自动补全文件名node 文件名开头+tab
  • 清空当前行输入内容esc
  • 关闭当前行ctrl+c
  • 清屏cls

fs文件系统模块

  • 引入fs模块require('fs')
  • 读取文件readFile(path[,option],callback(err,data))
  • 写入文件writeFile(path,data[,option],callback(err))
    • 写入内容会替代原来内容
    • 文件不存在自动创建
  • __dirname文件当前所处目录
    • path一般写成path.join(__dirname , '/xx/xx...')
    • 如果用./../有时会出现拼接出错变成xxx./xx/xx
//引入fs模块
const fs = require('fs')

//读取
fs.readFile('./text/01test.text', 'utf8', function (error, data) {
	console.log(error, '-----', data)
})

//写入
fs.writeFile('./text/01test.text', '写入内容', function (error) {
	console.log(error)
})
/*成功err为null*/

path模块

  • 引入path模块require('path')
  • 拼接路径path.join(__dirname , 'xx/x/x' , 'x/x/x')(路径都推荐这样写)
  • 获取路径中的文件名path.basename(url)
  • 获取路径的扩展名path.extname()

http模块

  • 引入http模块require('http')
  • 创建服务器实例http.createServer()
  • 为服务器绑定事件server.on('事件名',callback(request,response))
    • request,response分别为请求对象与响应对象
      • request.url请求路径
      • request.method请求类型
      • response.end()响应数据
      • response.setHeader('Content-Type','text/html; charset=utf-8')设置响应头,解决乱码
  • 监听端口server.listen(端口号,callback())
//导入http模块
const http = require('http')

//创建web服务器实例
const server = http.createServer()

//为实服务器绑定事件,监听客户端请求
server.on('request',function(request,response){
	console.log('有人访问')
})

//监听端口
server.listen(8080,()=>{
	console.log('服务器启动咯')
})

向服务器请求页面实例

const fs = require('fs')
const path = require('path')
const http = require('http')

const app = http.createServer()
app.on('request', (request, response) => {
	let url = request.url
	let fpath = path.join(__dirname, url)
	// response.setHeader('Content-Type','text/html;charset=utf-8')//加了这行相当于以后请求的所有内容格式utf8
		fs.readFile(fpath, 'utf8',(error, data) => {
			response.end(data)
		})
})
app.listen(5000, () => {
	console.log('服务器启动')
})

当客户端解析html时,发现其他路径的引用如css,会再次向服务器发送请求

模块化

commonJs规范

module对象

  • 每个模块里都有一个module对象存储了当前模块的信息
  • module.exports对象
    • 外部require引用模块时,引用的是module.exports对象

exports对象

  • module.exports===exports//ture

最后导出以module.exports为准

npm与包

认识与使用

  • 安装包后会统一放在node_models文件夹中
  • npm i xxx@版本号之前先npm init -y创建package.json文件一下,不然有可能不是安装在当前目录
  • 版本号规范4.22.3大版本号.功能版本号.bug修复版本号
    • 前面的数字更新,后面的数字清零
  • 安装所有项目所依赖包npm i,全局-g
  • 卸载指定包npm uninstall xxx ,全局-g

全局包默认安装路径C:\Users\用户目录\AppData\Roaming\npm\node_modules

  • 把安装的包记录在devDependencies节点,代表项目开发时用,但是上线后不使用的包npm i xxx -D完整写法--save-dev
  • package.json内的字段意义
    • dependencies核心依赖包:开发上线都需要用的包-S
    • devDependencies开发依赖包:开发用上线不用-D
  • 查看获取包的服务器/获取当前包的镜像源npm config get registry
  • 安装淘宝镜像npm config set registry=http://registry.npm.taobao.org/
    • 每隔10分钟将海外npm服务器上的包拷贝到国内服务器解决下载慢的问题
  • 将nrm安装为全局工具npm i nrm -g
  • 查看所有可用镜像源nrm ls
  • 切换镜像源nrm use taobao
  • 包的package.json文件里必须包括三个属性:name包名,version版本号,main包的入口
    • 详细https://yarnpkg.com/zh-Hans/docs/package.json

常用包

  • i5ting_toc.md文档转化为html
    • i5ting_toc -f 路径 -o
  • nodemon自动重启服务器

制作并发布自己的包

  • 创建文件夹xuzhou_tools
  • 文件夹内创建三个文件
    • index.js入口文件
    • README.md说明文件
    • package.json
{
	"name": "xuhzou_tools",//包名
	"main": "./index.js",//入口文件
	"version": "1.0.0",//版本号
	"description": "实验我自己的包",//描述
	"keywords": [//搜索关键子"xuzhou","tools"],
	"license": "ISC"//开源协议
}
  • npm login登录自己的npm账号
  • npm publish发布包到npm官网

登录账号要镜像源要切换到官网
发布时候要切到包目录下

  • npm unpublish 包名 --force删除包:只能删除72小时以内发布的包

模块化加载机制

  • 自定义模块加载机制
    • require()引入自定义模块时必须要加./或…/不然会优先引入内置模块再第三方模块,
    • 省略文件后缀如果找不到指定文件,会优先执行同名.js文件再.json最后.node最最后报错
  • 第三方模块加载机制
    • 逐级向上找node_module文件夹
  • 目录加载机制
    • 先找package.json文件中的main属性指定入口文件
    • 如果没有package.json文件,执行index.js文件

express框架

http模块的封装

基本使用

  • 安装npm i express
  • 导入模块const app = require('express')
  • app.get(url,callback(request,response))
    • request.query默认为空{}包含用户传递而来的query参数
      • 127.0.0.1:8080/?id=2&de=s客户端请求
    • request.params默认为空{}包含用户传递而来的params动态参数
      • 127.0.0.1:8080/xz/xs客户端请求
    • response.send()向服务端发送响应数据
  • app.post()同理
//导入模块
const express = require('express')
const app = express()
app.get('/',(request,response)=>{
	response.send(request.query)
})
app.post('/:name/:age',(request,response)=>{
	response.send(request.params)
})
//对外托管静态资源
app.use(express.static('./text'))//路径前缀可空
//启动服务器
app.listen(8080,()=>{
console.log('服务器启动')
})

静态资源

  • app.use('路径前缀如/page',express.static(url))对外托管静态资源
    • 127.0.0.1:8000/路径前缀/url下有的文件
    • 对外托管多个静态资源就多用几次app.use(express.static(url))
    • 如果各个目录里有同名文件,按托管先后顺序向外托管

路由模块化

  • 一般把挂载路由的步骤单独写在一个js文件里
  • 再在启动服务器js文件中注册路由
const express = require('express')
//创建路由实例对象
const router = express.Router()
//挂载路由
router.get('/',(request,response)=>{
	response.send(request.query)
})
//导出
module.exports=router

//启动服务器js文件中注册路由
const router = require('./路由独立模块')
app.use('路由前缀',router)

中间件

应用级别中间件
  • 全局中间件
    • 在匹配路由之前都需要通过全局中间件
//注册全局中间件
app.use((req,res,next)=>{
	console.log('中间件被调用啦')
	next()
})
  • 所有全局中间件共享一份requestresponse
  • 全局中间件按定义顺序执行
  • 局部中间件
定义中间件
const mw = (res,res,next)={}
const mw2 = (res,res,next)={}
局部使用中间件
app.get('/',[mw,mw2],(req,res)=>{})
//或者
app.get('/',mw,mw2,(req,res)=>{})

中间件要在路由之前定义

路由级别中间件
  • router.use(中间件函数)
错误级别中间件
  • app.use((err,req,res,next)=>{})注册错误级别中间件

错误级别中间件必须注册在路由之后,他会在抛出错误之后立即执行

express内置中间件
  • express.json()解析请求体的json中间件函数
app.use(express.json())
app.get('/json',(request,response)=>{
	console.log(request.body)
	response.send('ok')
})
  • express.urlencoded()解析请求体的urlencoded中间件函数
第三方中间件

安装引用注册…

自定义中间件
  • 自定义中间件中需要监听requestdata事件(每次传送数据触发)和end事件(数据传送结束触发)
function(req,res,next){
  let str = ''
  req.on('data',(chunk)=>{
    str += chunk
  })
  req.on('end',()=>{
    req.body=qs.parse(str)//见下方
  })
  next() 
}

定义接口

  • 创建服务器
  • 创建路由模块
  • 注册路由模块

querystring模块

//导入
const qs = require('querystring')
//将字符串转换成对象
qs.parse(str)

跨域

  • cors中间件解决跨域
    • 安装导入使用
    • 默认只支持9个响应头和get,post,HEAD三中响应方式
npm i cors
const cors = require('cors')
app.use(cors())
  • 设置响应头解决跨域
    • response.setHeader('Access-Control-Allow-Origin','*')
    • .setHeader
      • *改为固定url表示这有这个路径可以跨域
      • Origin改为Headers,*改为'响应头1,响应头2'表示还可以允许这些响应头
      • Origin改为Methods*改为'POST,DELEDE,'表示支持这两种响应方式
  • jsonp解决跨域
    • 只支持get请求的跨域
    • <script src='url'></script>
    • 服务器配置jsonp接口时必须写在app.use(cors())前面,不然还是cors接口
  //客户端
<script src="http://127.0.0.1:8080/jsonp"></script>
//服务器
app.get('/jsonp',(request,response)=>{
response.send(`alert('我来自服务器')`)//字符串形式的js代码
})

body-parser中间件

  • 用于将post请求体的数据解析
  • 安装,导入
  • 使用
const bodyParser = require('body-parser');
app.use(bodyParser.json());//解析json数据
app.use(bodyParser.urlencoded({ extended: false }));//解析url类型数据

现在express一般都内置了直接

app.use(express.urlencoded({ extended: true }))
app.use(express.json())

express-session认证

  • 常用于不需要跨域
  • 安装session中间件npm i express-session
  • 导入中间件const session = require(‘express-session’)
  • 使用中间件并配置app.use(session({}))
const express = require('express')
const session = require('express-session')
const cors = require('cors')
const bodyParser = require('body-parser');

const app = express()、
app.use(cors())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.use(session({
	secret: 'admin',//值自定
	resave: false,//固定写法
	saveUninitialized: true//固定写法
}))
app.post('/login', (req, res) => {
	if(req.body.username !=='admin' || req.body.password !== '0000'){
		return res.send({status:1,msg:'登录失败'})
	}
	req.session.user = req.body//把请求体数据保存起来
	req.session.isLogin = true//登陆状态设置为真
	res.send('登陆成功')
})
app.listen(8080, () => {
	console.log('服务器启动')
})

get请求没有请求体,ajax发送数据send(),数据类型由请求头的content-type决定

JWT认证

  • 常用于需要跨域
  • 最流行
  • 存储在localStorage或sessionStorage
  • 由3部分组成
    • Header.Payload(用户加密信息).Signature

使用

  • 安装两个包,jsonwebtoken和express-jwt
    • jsonwebtoken用于加密用户信息成JWT字符串
    • express-jwt用于解密JWT字符串成JSON对象
  • 导入
  • 定义secret密钥
  • jsonwebtoken.sign({})生成JWT字符串
    • {}中包含3个参数用户信息{},密钥’',有效时间{expiresIn: ‘30s’}
  • 注册expressJwt中间件
    • 配置app.use(expressJWT({secret:密匙,algorithms: [“HS256”]}).unless({path:[/正则/]}))
      • secret与algorithms必要
    • unless指定哪些路径不需要访问权限
    • 这个中间件会给req添加一个user属性存储解析的用户信息

expressJwt这个包用法已经变了,到官网差查

const express = require('express')
//导入jsonwebtoken
const jwt = require('jsonwebtoken')
//导入express-jwt
const expressJwt = require('express-jwt')
const app = express()
const bodyParser = require('body-parser');
//定义密钥
const secretKey = 'xuzhou'
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
//定义post接口,把生成的token传给客户端
app.post('/enter', (req, res) => {
	let tokenStr = jwt.sign({ username: req.body.username }, secretKey, { expiresIn: '300s' })
	res.send({
		status: 200,
		msg: '登录成功',
		token: tokenStr
	})
})
//注册express-jwt中间件,客户端登录时,中间件把token解析成用户数据并存储到req.user中
app.use(expressJwt({ secret:secretKey ,algorithms: ["HS256"]}).unless({ path: [/\/api\//] }))
//定义登录接口,验证token解析后是否为用户,返回相应值
app.get('/enterToken', (req, res) => {
	if (req.user.username === 'xz') {
		res.send('你已经登录')
	}else{
		res.send('你的token不对')
	}
})
app.listen(8080, () => {
	console.log('服务器启动');
})

注意中间件注册顺序
添加请求头Authorization 请求头值Bearer+空格+token
才能把token传给服务器

bcryptjs加密包

  • 安装,导入
    - bcrypt.hashSync(需要加密的字符串, salt);
    • salt表示盐,百度

表单验证包

太多,看喜好百度用

注意

express不允许send两次

Mysql

安装

  • 百度

图视化工具使用

  • 百度

sql语句

  • 百度有语句大全
  • 常用
    • insert into users (name,password) values ('xz','520')
    • update users set password = '5201314' where id < 6
    • delete from users where id = 6
    • select * from users where id = 4 and name = 'ls'
    • select * from users order by id desc降序
    • select * from users order by id asc升序
    • select * from users order by id asc, name desc
    • select count(*) from users where name = 'xz'符合条件总数
    • select count(*) as total from users where name = 'xz'起别名

js文件中操作数据库

  • 安装模块npm i mysql
  • 查询和增添信息
//导入mysql模块
const mysql = require('mysql')
const database = mysql.createPool({
	host:'127.0.0.1',//数据库地址
	user:'root',//登录数据库账号
	password:'admin123',
	database:'demo01'//指定操作哪个数据库
})
//第一种增加写法
const user = {name:'xxxx',password:'3270280820909130910'}
//?占位
const sqlStr = 'insert into users (name,password) values (?,?)'
//[]中的数据一一对应占位符
database.query(sqlStr,[user.name,user.password],(error,results)=>{
	if(error){
		console.log(error.message)
	}else{
		console.log(results.affectedRows);//results.affectedRows的值为1表示执行成功
	}
})
//第二种增加写法
const user2 = {name:'wo',password:'3270280820909130910'}
//?占位
const sqlStr2 = 'insert into users set ?'
//{}  
database.query(sqlStr2,user2,(error,results)=>{
	if(error){
		console.log(error.message)
	}else{
		console.log(results.affectedRows);//results.affectedRows的值为1表示执行成功
	}
})
//查询
database.query('select * from users',(error,results)=>{
	if(error){
		console.log(error.message)
	}else{
		console.log(results);
	}
})
  • 更新和删除
//第一种更新
const user = { id: 7, name: 'music', password: '00000000' }
const sqlStr = 'update users set name = ?,password = ? where id = ?'

database.query(sqlStr, [user.name,user.password,user.id], (err, results) => {
	results.affectedRows === 1 ? console.log('更新成功') : console.log('错了');
})
//第二种更新
const user = { id: 7, name: 'music', password: '00049894944' }
const sqlStr = 'update users set ? where id = ?'

database.query(sqlStr, [user,user.id], (err, results) => {
	results.affectedRows === 1 ? console.log('更新成功') : console.log('错了');
})
//删除
const sqlStr = 'delete from users where id = ?'
database.query(sqlStr,12,()=>{})
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值