执行命令:
express --view=ejs midapp
cnpm install
nodemon ./bin/www
express.urlencoded():解析body的函数
express.Router();:实例化路由模块,此路由模块相当于一个小的app实例
跨域:域名或者端口不同都算跨域
跨域问题解决:服务器设定允许访问即可(设置Access-Control-Allow-Origin请求头)
// 允许前端跨域请求的中间件
api.use((req, res, next) => {
// 允许所有源
res.append('Access-Control-Allow-Origin', "*");
// 允许所有请求类型
res.append('Access-Control-Allow-Content-Type', "*");
next();
})
1.应用层中间件
app.js
var express = require('express');
var path = require('path');
var app = express();
let router1 = require('./routes/mall');
let api = require('./routes/api');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.urlencoded({
extended: false
}));
app.use(express.static(path.join(__dirname, 'public')));
// 添加中间件
// 如果不写next,将被截获在此,不能继续向下执行
// 一般中间件是处理req,或者res的
app.use(function (req, res, next) {
res.addNum = function (a, b) {
return a + b;
}
console.log("访问任何页面,此函数都会被调用");
next();
})
// 封装lcQuery中间件
app.use(function (req, res, next) {
try {
let splitRes = req.url.split('?');
if (splitRes.length > 0) {
let queryStr = req.url.split('?')[1];
if (queryStr == undefined) {
next();
}
// 对表单提交的键值对进行分割
let keyValueArr = queryStr.split('&');
// 设置一个query对象,将键值对以对象的属性形式进行保存
let query = {};
keyValueArr.forEach(function (item, i) {
// searchKey=admin,进行分割
let key = item.split('=')[0];
let value = item.split('=')[1];
query[key] = value;
})
req.lcQuery = query;
next();
} else {
next();
}
} catch (error) {}
})
app.get('/', (req, res) => {
console.log(req.lcQuery);
res.send("首页" + res.addNum(1, 2));
})
app.use('/mall', router1);
app.use('/api', api);
module.exports = app;
2.路由中间件
mall.js
let express = require('express');
// 实例化路由模块
let router1 = express.Router();
router1.use(function (req, res, next) {
console.log("判断用户是不是商城用户");
next();
})
router1.get('/', (req, res) => {
res.send("商城首页");
})
router1.get('/list', (req, res) => {
res.send("商城产品列表页");
})
module.exports = router1;
api.js
let express = require('express');
let sqlQuery = require('../lcMysql');
// 实例化路由模块
// 提供Ajax请求的接口
let api = express.Router();
// 允许前端跨域请求的中间件
api.use((req, res, next) => {
// 允许所有源
res.append('Access-Control-Allow-Origin', "*");
// 允许所有请求类型
res.append('Access-Control-Allow-Content-Type', "*");
next();
})
async function getCataory() {
let sqlStr = "select * from cataory";
let result = await sqlQuery(sqlStr);
return Array.from(result);
}
// 提供什么分类下的,第N页book的数据
api.get('/book/cataory/:cid/page/:pid', async (req, res) => {
let page = parseInt(req.params.pid);
let cid = req.params.cid;
let strSql;
let arr;
let result;
if (cid == 0) {
strSql = "select id,bookname,bookimg,author,cataory from book limit ?,1";
arr = [(page - 1) * 1]; //*num:就是乘每页的书本数,由数据库语句的limit的第二位决定
result = await sqlQuery(strSql, arr);
} else {
strSql = "select id,bookname,bookimg,author,cataory from book WHERE cataory in (SELECT cataory from cataory WHERE id=?)limit ?,1";
arr = [cid, (page - 1) * 1]; //*num:就是乘每页的书本数,由数据库语句的limit的第二位决定
result = await sqlQuery(strSql, arr);
}
// 获取总页数
let strSql1 = "select count(id) as num from book WHERE cataory in (SELECT cataory from cataory WHERE id=?)";
let result1 = await sqlQuery(strSql1, arr);
let pageAll = Math.ceil(result1[0].num / 1);
let startPage = (page - 4) < 1 ? 1 : (page - 4);
let endPage = (page + 5) > pageAll ? pageAll : (page + 5);
let options = {
books: Array.from(result),
cataorys: await getCataory(),
pageAll,
page,
cid,
startPage,
endPage
}
res.json(options);
})
api.get('/list', (req, res) => {
res.send("商城产品列表页");
})
module.exports = api;
api应用的book的history
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/jquery.min.js"></script>
</head>
<body>
<h1>历史相关书籍</h1>
<script>
let httpUrl = '/api/book/cataory/3/page/1';
$.ajax(httpUrl).then(function (res) {
console.log(res);
res.books.forEach((item, i) => {
$('body').append("<h2>" + item.bookname + "<h2>");
})
})
</script>
</body>
</html>