express中间件和路由
路由
-
路由的目的就是为了区分接口,清除每个接口所需要执行的事情、
-
当接口相同 时,可以通过自带参数type来区别接口,
-
两者区别:第一种用于路由区分,这种情况的的优点,可以让路由快速判断,解决问题,通过参数传递,不能直接取到类型,需要解析数据,判断对应的0 是什么?1是什么?
-
从路由的角度说,直接使用路由区分是最简单的
-
长连接与短链接的区别:
- 短链接可以通过路由告诉服务器目的
- 长连接需要使用属性的type类型来判断
-
服务端与前端的路由区别
- 前端路由加#,是哈希路由,哈希的目的是产生历史记录,显示每一个页面
- 服务端路由为了区分接口。
// package.json
{
"name": "express1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "cross-env PORT=4001 nodemon server.js"
},
"dependencies": {
"express": "^4.18.2",
"cors": "^2.8.5",
"multer": "1.4.3"
},
"devDependencies": {
"nodemon": "^2.0.22",
"cross-env": "^7.0.3"
},
"keywords": [],
"author": "",
"license": "ISC"
}
// userRouter.js
const express=require('express')
const router=express.Router()
router.get('/',function(req,res){
res.send('aaaa请求成功')
})
router.post('/add',function(req,res){
console.log(req.body)
res.send({err:null,msg:"登录成功"})
})
router.post('/logout',function(req,res){
console.log(req.query)
res.send({err:null,msg:"退出登录"})
})
module.exports=router
// server.js
const express=require("express"); // 导入express框架
const app=express(); // 创建一个变量名为app
const cors=require("cors"); // 导入express的cors模块
const multer=require("multer")(); // 导入express的multer模块
const userRouter=require("./userRouter");
const shoppingRouter=require("./shoppingRouter");
app.use(multer.none()); // 处理不需要上传文件的请求
app.use(express.urlencoded({extended:true})) // 解析编码为 URL 编码的请求体
app.use(express.json()); // 解析 JSON 格式的请求体
app.use(cors()); // 用于启用跨域资源共享
// 静态服务器
app.use(express.static("./public"))
// 访问根路径
app.use("/",function(req,res,next){
res.set("set-Cookie","a=33");
next();
})
// 访问路由
app.use("/user",userRouter);
app.use("/shopping",shoppingRouter);
app.listen(process.env.PORT || 8080);
// 前端
ajax('/user/logout',{user:"张三",password:"13456"})
async function ajax(router,data){
var res = await fetch("http://localhost:4001"+router,{
method:"post",
body:JSON.stringify(data),
headers:{
"Content-Type":"application/json"
}
})
var data=await res.json()
console.log(data)
}
post请求实现过程
- 前端
ajax('/user/add',{user:"张三",password:"13456"})
async function ajax(router,data){
var res = await fetch("http://localhost:4001"+router,{
method:"post",
body:JSON.stringify(data),
headers:{
"Content-Type":"application/json"
}
})
var data=await res.json()
console.log(data)
}
- server
const express=require('express')
const app=express()
const cors=require('cors')
const userRouter=require('./userRouter')
app.use(cors())
app.use(express.json()) // 解析前端发过来的数据
app.use("/user",userRouter)
app.listen(process.env.PORT || 8080)
- userRouter
const express=require('express')
const router=express.Router()
router.get('/',function(req,res){
res.send('aaaa请求成功')
})
router.post('/add',function(req,res){
console.log(req.body)
res.send({err:null,msg:"登录成功"})
})
module.exports=router
路由中间件
- 通过路由来访问指定的二级路由
内置中间件
- 静态服务器 :在express中内置中间件仅有一个,就是静态处理,可以快速将静态文件返回给前端
app.use(express.static("./publc"))
错误中间件
- 错误处理中间件和其他中间件定义类似,只是要使用 4 个参数,而不是 3 个,其签名如下: (err, req, res, next)。
app.use(function(err, req, res, next) {
console.error(err.stack)
res.status(500).send('Something broke!')
})
express生成器
- 下载
npm i express-generator -g
- 视图创建
express -e
- 修改package配置
{
"name": "express1",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"ejs": "~2.6.1",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"morgan": "~1.9.1",
"cors":"^2.8.5",
"multer":"1.4.3"
},
"devDependencies": {
"nodemon":"^2.0.22",
"cross-env":"^7.0.3"
}
}
- 下载插件
npm i
// 修改配置
"scripts": {
"start": "cross-env PORT=4001 nodemon ./bin/www"
},
- 启动
npm start
art-template
SSR
- 直接访问服务器,服务器吐出页面,最大特点:就是直接跳转新页面,卸载当前页面,会产生重新渲染
- 典型的就是:登录注册,注册成功,等待3s后返回数据
- SEO的最大作用就是引流
CMS网站发布系统
优化方案
- 减少白屏时间:script加载时间过长,这时候使用异步就可以减少,样式的使用也会影响
- 提升加载性能:把很多要加载的内容合并在一起,做压缩,比如需要加载10个js,将他合并成1个
- 加速减少HTTP请求:使用CDN加载公共库,
- 强缓存【服务器】和协商缓存【服务器和客户端】:强缓存就是告诉你这个东西,在规定的时候内不要在向我这边请求,协商缓存就是在请求的时候添加last-modified:是一个时间标识缓存的最后修改时间
- 域名收敛:用于移动端。
- 域名发散:用于PC端
- 并发:用一个时间往服务器请求数据,开启多线程,开启多进程,开启集群;仍然会上线,最高限制。
- 怎么解决高并发?添加验证码,域名发散【多个域名访问一个ip地址】。
- DNS:域名解析系统,
- 使用get请求代替post请求:用get代替post主要目的就是调用缓存
- 减少预检请求:
- DNS预解析:在head头部中,先进行预解析,跳转到指定域名就是指定的地址,如果跳转页面过多,就是用dns-prefetch
- 懒加载:创建一个script。document侦听他,只有用到的时候才调用它。组件的使用也都是懒加载。vue中的路由也是懒加载,
- 减少请求内容的体积:开启自动压缩
- 优化用户等待体验:白屏使用加载进度条、loading图、骨架屏代替等;
前端art-template
- 插值
{{ title }}
- 基本使用
<head>
<script src="./node_modules/art-template/lib/template-web.js"></script>
</head>
<body>
<div id="app"></div>
<script id="tp" type="texe/html">
<h3>{{value}}</h3> // 今天星期四
<p>{{key}}</p> // 关键知识点呢
<p>{{day['key']}}</p> // 18
<p>{{a?b:c}}</p> // 3
<p>{{a || b}}</p> // 10
<p>{{a + b}}</p> // 13
</script>
<script>
var user={name:"zhangsan",age:30}
var app=document.querySelector('#app')
var str=template("tp",{
value:'今天星期四',
day:{key:18},
key:"关键知识点呢",
a:10,
b:3,
c:6
})
app.innerHTML=str
console.log(str)
</script>
</body>
</html>
- $data:整个对象
- 原文输出
<div>{{@ value}}</div> // 今天星期四
- list数组渲染
- 循环对象
art标准语法
- 基础语法
{{value}}
{{data.key}}
{{data['key']}}
{{a ? b : c}}
{{a || b}}
{{a + b}}
// 答案如上
- 条件语法
{{if value}}
<p>{{value}}</p>
{{else if key}}
<span>{{key}}</span>
{{/if}}
// 要是value值不存在将执行key,得到”关键知识点呢“
// 如果存在value值,将执行value,得到”今天星期四“
- 循环语法
{{each target}}
{{$index}} {{$value}}// 0 得 1 到 2 我 3 的 4 主 5 题
{{/each}}
{{each user $key $val}}
<div>{{$key}}:{{$val}}</div>
{{/each}}
// user:{key:"zhangsan",val:"18"},
/*
得到:
zhangsan:key
18:val
*/
- 变量
data:{
sub:{
content:"前端学习快乐成长"
},
num:{
s1:"2023-3-31"
}
}
{{set temp=data.sub.content}}
{{set t=data.num.s1}}
{{temp}} // 前端学习快乐成长
{{t}} // 2023-3-31
服务端art-template
- 添加配置
atr-template
express-art-template
- 添加解析art
// app.js
var template=require('art-template')
app.set('view engine', 'art');
template.defaults.imports.rendomColor=function(){
return Array(6).fill(1).reduce((v,t)=>v+(~~(Math.random()*16)).toString(16),'#')
} // 随机色
- 使用art替换ejs
<!--layout.art-->
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{{block 'title'}}My Site{{/block}}</title>
{{block 'head'}}
<link rel="stylesheet" href="main.css">
{{/block}}
</head>
<body>
{{block 'content'}}{{/block}}
</body>
</html>
<!--index.art-->
{{extend './layout.art'}}
{{block 'title'}}{{title}}{{/block}}
{{block 'head'}}
<link rel="stylesheet" href="custom.css">
{{/block}}
{{block 'content'}}
<p>This is just an awesome page.</p>
{{/block}}
// 服务端
var express=require("express");
var app=express();
app.use(express.static("./"));
app.engine('art', require('express-art-template'));
app.get("/",function(req,res){
res.render("./index.art",{title:"xietian"});
})
app.listen(4001);
- 子模板
{{include './header.art'}}
{{include './header.art' data}}
- 过滤器
var express=require("express");
var template=require("art-template");
var app=express();
app.use(express.static("./"));
app.engine('art', require('express-art-template'));
template.defaults.imports.randomColor=function(){
var col="#";
for(var i=0;i<6;i++){
col+=Math.floor(Math.random()*16).toString(16);
}
return col;
}
template.defaults.imports.getSum=function(a,b){
return a+b;
}
app.get("/",function(req,res){
res.render("./c.art",{data:"xietian"});
})
app.listen(4001);
{{extend './layout.art'}}
{{block 'title'}}{{data}} site{{/block}}
{{block 'head'}}
<link rel="stylesheet" href="./views/b.css">
{{/block}}
{{block 'content'}}
<div style='color:{{randomColor}}'}>asdb</div>
<div>{{getSum(5,6)}}</div>
{{/block}}
CMS
- 配置package
"dep":{
expres
}
mongodb
- 启动
PS C:\WINDOWS\system32> net start MongoDB
MongoDB Server (MongoDB) 服务正在启动 .
MongoDB Server (MongoDB) 服务已经启动成功。
- package配置
"dep":{
"cors"
"art-temp"
"express-art"
"mongoose"
}
"dev":{
"nodemon"
"cross-env"
}
"start":"wwww"
app.js
var cores=require("cors")
var multer=require("multer"){}
var template=require("art-remplate")
app.set("art",rqeuire("express-art-template"))
socket
- 后台聊天室
// client.js
const net = require('net')
const readline=require('readline')
var order=readline.Interface({
input:process.stdin,
output:process.stdout
})
var socket=new net.Socket()
socket.connect(4001,"10.9.41.101",()=>socket.write("张三"))
socket.on("data",dataHandler)
inputMsg()
function inputMsg(){
order.question("要发出的消息:",function(msg){
socket.write(msg)
inputMsg()
})
}
function dataHandler(msg){
console.log("\n"+msg+"")
inputMsg()
}
// server.js
const net = require('net')
var server = net.createServer()
var list={}
init()
function init(){
server.on('connection',connectionHandler).listen(4001)
}
function connectionHandler(client){
client.on("data",msg=>msgHandler(msg,client))
client.on('error',error=>errorHandler(error,client))
client.on('close',data=>errorHandler(data,client))
}
function msgHandler(msg,client){
if(!client.name){
client.name=msg
list[client.name]=client
}else{
for(var key in list){
list[key].write(client.name+"说:"+msg+"")
}
}
}
function errorHandler(data,client){
client.end()
}