diff --git "a/\345\274\240\344\275\263\346\225\217/20260330\344\270\255\351\227\264\344\273\266.md" "b/\345\274\240\344\275\263\346\225\217/20260330\344\270\255\351\227\264\344\273\266.md" new file mode 100644 index 0000000000000000000000000000000000000000..8b9072e94f00fe9410d98ff6d0a5b7627113e389 --- /dev/null +++ "b/\345\274\240\344\275\263\346\225\217/20260330\344\270\255\351\227\264\344\273\266.md" @@ -0,0 +1,108 @@ +# 简答题 +## 第一题:什么是中间件?它在Express中起什么作用? +中间件 = 请求处理管道 + +所有功能(解析、日志、鉴权、跨域、错误处理)都是靠中间件实现的 + +路由本身,本质上也是一种 “匹配路径后才执行” 的中间件 +## 第二题:中间件函数中的next()函数有什么作用?如果不调用会怎样? +next() = 放行,继续执行下一个中间件 / 路由 + +不调用 next() 且不返回响应 = 请求挂起、前端超时 +## 第三题:应用级中间件和路由级中间件有什么区别? +应用级中间件:全局通用,绑在 app + +路由级中间件:局部专用,绑在 router,只对某一组接口生效 +## 第四题:错误处理中间件和普通中间件有什么区别? +普通中间件:3 个参数,处理正常请求 + +错误处理中间件:4 个参数,专门捕获 next (err) 抛出的错误 +## 第五题:如何在中间件中传递数据给后面的处理函数? +在中间件中将数据挂载到 req 对象上,后面的中间件和路由处理函数就可以通过 req 访问到这些数据。 +# 操作题 +## 第一题:IP限制中间件:创建一个中间件,记录请求IP并限制某些IP访问。 +``` +// 黑名单IP +const blackIP = ['127.0.0.1'] + +// IP限制中间件 +const ipFilter = (req, res, next) => { + const ip = req.ip + console.log('请求IP:', ip) + + if (blackIP.includes(ip)) { + return res.send('禁止访问') + } + next() +} + +// 使用 +app.use(ipFilter) +``` +## 第二题:请求超时中间件:创建一个中间件,如果请求超过指定时间未响应,返回超时错误。 +``` +// 请求超时中间件(5秒超时) +const timeout = (req, res, next) => { + const timer = setTimeout(() => { + res.status(504).send('请求超时') + }, 5000) + + // 正常响应时清除定时器 + const end = res.end + res.end = (...args) => { + clearTimeout(timer) + end.apply(res, args) + } + + next() +} + +// 使用 +app.use(timeout) +``` +## 第三题:请求体验证:创建一个中间件,验证请求体中的必填字段。 +``` +// 校验 body 必须有 name 和 age +const validateBody = (req, res, next) => { + const { name, age } = req.body + + if (!name || !age) { + return res.status(400).send('缺少必填字段:name 或 age') + } + + next() +} + +// 使用 +app.use(express.json()) // 必须先解析body +app.post('/user', validateBody, (req, res) => { + res.send('验证通过') +}) +``` +## 第四题:统一错误响应:改造错误处理中间件,统一返回格式。 +``` +import lombok.Data; + +@Data +public class R { + private int code; + private String msg; + private Object data; + + public static R ok(Object data) { + R r = new R(); + r.code = 200; + r.msg = "success"; + r.data = data; + return r; + } + + public static R fail(int code, String msg) { + R r = new R(); + r.code = code; + r.msg = msg; + r.data = null; + return r; + } +} +``` \ No newline at end of file diff --git "a/\345\274\240\344\275\263\346\225\217/20260401\346\250\241\345\235\227\345\274\225\346\223\216\347\254\224\350\256\260.md" "b/\345\274\240\344\275\263\346\225\217/20260401\346\250\241\345\235\227\345\274\225\346\223\216\347\254\224\350\256\260.md" new file mode 100644 index 0000000000000000000000000000000000000000..09ab1df74e0760099ddfc5a55c620133f61a1f6a --- /dev/null +++ "b/\345\274\240\344\275\263\346\225\217/20260401\346\250\241\345\235\227\345\274\225\346\223\216\347\254\224\350\256\260.md" @@ -0,0 +1,48 @@ +# ejs的笔记 +## 第一步:安装 +npm install ejs express +## 第二步:express配置ejs(页面放在view文件夹里,后缀.ejs) +``` +const express = require('express') +const app = express() + +// 1. 设置模板引擎为 ejs +app.set('view engine', 'ejs') +// 2. 设置模板文件存放目录(默认 views 文件夹) +app.set('views', './views') + +app.listen(3000, ()=>{ + console.log('服务启动') +}) +``` +标签 作用 +<%= %> 输出变量,转义 HTML(安全) +<%- %> 输出 HTML,不转义(富文本用) +<% %> 写 JS 代码(if/for/ 变量,不输出) +<%# %> 注释(不会编译到页面) +## 小案例 +``` +<%- include('header', {title:'用户页'}) %> + +

欢迎 <%= username %>

+ +<% if(vip){ %> +

你是VIP会员

+<% } %> + + +``` +### js端 +``` +app.get('/user', (req,res)=>{ + res.render('index',{ + username: '李四', + vip: true, + news: ['公告1','公告2','公告3'] + }) +}) +``` \ No newline at end of file diff --git "a/\345\274\240\344\275\263\346\225\217/20260402\346\250\241\345\235\227\345\274\225\346\223\216\351\242\230.md" "b/\345\274\240\344\275\263\346\225\217/20260402\346\250\241\345\235\227\345\274\225\346\223\216\351\242\230.md" new file mode 100644 index 0000000000000000000000000000000000000000..30a9069014c05e0c66746e5a4d5ca90fddb5c3dd --- /dev/null +++ "b/\345\274\240\344\275\263\346\225\217/20260402\346\250\241\345\235\227\345\274\225\346\223\216\351\242\230.md" @@ -0,0 +1,179 @@ +# 简答题 +## 第一题:什么是模板引擎?它在Web开发中起什么作用? +模板引擎就是后端专用的 “HTML 自动拼装机器”: +拿模板 + 拿数据 → 自动生成完整动态网页,发给浏览器展示。 +## 第二题:EJS中<%= %>和<% %>有什么区别? +``` +<% + let name = "张三"; + if(age >= 18){ + msg = "成年人"; + } +%> + +

用户名:<%= name %>

+

状态:<%= msg %>

+``` +写逻辑、循环判断 → 用 <% %> +展示文字变量到页面 → 用 <%= %> +## 第三题:什么是MVC架构?每个部分分别负责什么? +MVC是一种项目分层架构思想,把代码拆分成三部分: + +M (模型) + V (视图) + C (控制器) +## 第四题:Express中如何配置和使用模板引擎? +先安装:npm install express ejs + +``` +const express = require('express') +const app = express() + +// ① 设置模板引擎为 ejs +app.set('view engine', 'ejs') +// ② 设置模板文件存放目录(默认就是 views,写上更清晰) +app.set('views', './views') +``` +js +``` +// 渲染 index.ejs,并且传数据给模板 +app.get('/', (req, res) => { + res.render('index', { + name: '小明', + age: 18 + }) +}) +``` +ejs +``` +

姓名:<%= name %>

+

年龄:<%= age %>

+``` +## 第五题:静态资源和模板文件有什么区别? +在express里用: +``` +app.use(express.static('public')) +``` +静态资源:直接发给浏览器,不改不动 +模板文件:后端加工填数据,动态生成网页 + +# 操作题 +## 第一题:博客列表页:使用EJS创建博客文章列表页,显示文章标题、作者、发布日期。 +先安装express和ejs:npm install express ejs +app.js +``` +const express = require('express') +const app = express() + +// 配置EJS模板引擎 +app.set('view engine', 'ejs') +app.set('views', './views') + +// 模拟博客数据(后端假数据) +const blogData = [ + { + title: 'Node.js入门教程', + author: '张三', + date: '2026-04-01' + }, + { + title: 'EJS模板引擎使用技巧', + author: '李四', + date: '2026-04-02' + }, + { + title: 'MVC架构详解', + author: '王五', + date: '2026-04-03' + } +] + +// 博客列表路由 +app.get('/blog', (req, res) => { + // 把博客数据传给EJS模板 + res.render('blogList', { list: blogData }) +}) + +// 启动服务 +app.listen(3000, () => { + console.log('服务器启动:http://localhost:3000/blog') +}) +``` +view/blogs.ejs +``` + + + + + 博客列表页 + + + +

博客文章列表

+ + + +``` +终端执行:node app.js + +浏览器打开:http://localhost:3000/blog +分页功能:为列表页添加分页,显示页码和上下页按钮。 + +## 第二题:文章详情页:创建文章详情页,点击标题可以查看文章内容。 +``` +// 引入 Node.js 内置模块 +const http = require('http'); +const url = require('url'); + +// 文章数据 +const articles = [ + { id: 1, title: "前端学习", content: "HTML + CSS + JS 是基础" }, + { id: 2, title: "JS 基础", content: "变量、函数、循环很重要" }, + { id: 3, title: "CSS 布局", content: "Flex 和 Grid 最好用" } +]; + +// 创建服务器 +const server = http.createServer((req, res) => { + const pathObj = url.parse(req.url, true); + const id = pathObj.query.id; + + // 文章列表页 + if (!id) { + res.writeHead(200, { 'Content-Type': 'text/html;charset=utf-8' }); + let html = '

文章列表

'; + articles.forEach(art => { + html += `

${art.title}

`; + }); + res.end(html); + } + // 文章详情页 + else { + const art = articles.find(item => item.id == id); + res.writeHead(200, { 'Content-Type': 'text/html;charset=utf-8' }); + if (art) { + res.end(` +

${art.title}

+

${art.content}

+ 返回 + `); + } else { + res.end('找不到文章'); + } + } +}); + +// 启动服务 +server.listen(3000, () => { + console.log('服务已启动:http://localhost:3000'); +}); +``` \ No newline at end of file