# 个人博客 **Repository Path**: mxlhhunna/blog ## Basic Information - **Project Name**: 个人博客 - **Description**: 个人博客:分享编程技术、生活感悟与创意想法的空间,适合寻找灵感和技术交流的开发者和爱好者。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-03-06 - **Last Updated**: 2025-03-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 前端项目的准备工作 1. 引入合适的UI框架 2. 处理默认的样式 3. 适应不同尺寸的屏幕(%) 4. css的预处理器(如less,sass,stylus # 后端 1. 初始化项目 (npm init -y) 2. 安装koa框架(npm i koa) 3. 安装koa-router框架 (npm i koa-router) 定义路由,封装了路由的使用 4. 定义mysql的配置文件 5. 封装数据库的连接 6. 封装xxx接口要执行的数据库操作的函数 7. koa默认是不支持post请求的,需要安装 @koa/bodyparser 框架 (npm i @koa/bodyparser), 解析post请求的请求体数据 被koa的实例对象app use掉的中间件就会有ctx和next,只有被app.use(router)的路由才生效 ## slot插槽 定义一个子组件,希望该子组件只做一个外层容器,子组件中间还可以放上dom元素,那么 就要在该子组件上放上slot插槽 1. 匿名插槽 2. 具名插槽 ## 跨域 http:// localhost :3000 /article/getNewsArticleList 协议 域名 端口号 路径 - 浏览器的同源策略 1. 协议相同 2. 域名相同 3. 端口相同 跨域是浏览器自带的一个同源策略,为了安全性考虑。规定必须同一个协议同一个域名同一个端口,浏览器才认为是同一个源的。 - 跨域是浏览器不接受后端的响应数据 npm install @koa/cors --save 可以使用npm官网上别人封装的的@koa/cors来解决跨域问题 - 引入 import 的时候要不要加花括号{}? 抛出的时候 export 有default 就不用{},没有default 要加{} - 设置最小高度 min-hight: xx px 保证在数据不够时高度不至于太小,底部的footer正好在底部 - npm run dev 启动前端 node index.js 启动后端 --save表示最后打包会留下,而不是只留在开发环境 ## 媒体查询 @media screen and (max-width: 1200px) { .home-model_right{ display: none; } } # 登陆问题 1. 纯前端判断 判断本地存储中是否有token (这种方案是不严谨的) 2. 后端判断 ,判断token是否有效 3. 前后端都判断(用户没有登陆且没有耍小聪明的情况下,可以少发一个请求) # Promise.all()语法 Promise.all()里面放一个数组,数组里面放了多个promise,数组后面可以接.then(res =>{}),只有数组里面所有的函数promis都成功执行了之后,才会执行then里面的函数,then里面的参数res是数组里所有函数resolve出来的值的元素的数组集合 Promise.all([a(),b()].then(res =>{})) # 小知识 -D 全称是--save-dev 保留在开发环境 项目写完一打包,源代码不会打包进去 - __dirname 这个node关键字是当前js脚本文件所在文件夹在电脑上的绝对路径,有了这个获取绝对路径的方式,不管是在哪台电脑上都可以获取到正确的绝对路径。commonJS规范 把代码写在模块里再引入回来 规定了要用require引入 但是windows环境下不支持commomJS 只支持ESModule规定用import {} from '' 所以不能用__dirname用import.meta.url - 常见的页面初始化 html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } table { border-collapse: collapse; border-spacing: 0; } - 被koa use掉的函数就会有ctx和next - box-sizing: border-box; 可以用此解决内容超出父容器的问题。因为这样会使内容的尺寸=本身的内容+内外边距 加上内边距后往往要考虑再加上box-sizing: border-box - :deep(.el-input__wrapper) 当想要改elelmentUI的样式时,发现改不动,就用:deep(要改的ui名字) - 圆角处理 border-radius: 填px单位的数字时,无论多大都是两边圆的,中间是矩形 填%单位时,可以变成椭圆或圆 通常搭配overflow:hidden来使用 - overflow: hidden; 专门用来把容器变成bfc容器,可以解决浮动导致的父容器没有高度的问题 - 使用阿里的icon-font 先在index.html中的head标签里面引入 在要用到的地方用i标签 写2个类名,一个是iconfont,以一个是标签名 i标签是一种特殊的字体,所以他是用color改颜色,是行内元素,用font-size改大小,line-height改垂直居中, text-align:center改水平居中 - 怎么取消最后一个li的margin-bottom? 先用&:选中li,再用last-chirld选中最后一个li。 &:last-child{ margin-bottom: 0; } - jwt 在前端的请求拦截中,把token放在请求头的Authorization中(前端的A是大写的), 然后在后端通过ctx.request.headers.authorization拿到token(前端的a是小写的) - 在后端定义get接口 router.get() 第一个参数是接口地址如''/detail',第二个参数是函数体(回调函数),第三个参数是函数体,可以在后面一直接函数体,前一个函数要 await next()就行,会按顺序执行箭头函数(只有执行了next才会执行下一个函数) - get请求的参数 在后端通过ctx.query拿到 post请求的参数 在后端通过ctx.request.body拿到(需要安装koa-bodyparser来解析请求体 ) - router.get('/addLike',verify(),async(ctx,next) => { // 文章id 用户id const {article_id} = ctx.query }) verify()里面得到的参数怎么传给async(ctx,next)这个函数? ctx是一个对象 我直接往ctx里挂一个 ctx.user_id = decoded.id (直接挂在全局对象上) 这样一来,在下一个函数访问的是同一个ctx,也就可以拿到user_id了,ctxs是引用类型,在koa里始终代表同一个实例对象 - 前端朝后端发请求,这样用 get请求的参数这样写:{params:{参数放在这里}} axios.get('/article/getArticleDetailById',{ params:{id:id} }) post请求的参数直接放在对象里:axios.post('/article/getArticleDetailById',{id:id}) - 后端定义接口的步骤 1. 先拿到单例模式中的唯一实例对象router const Router = require('koa-router'); const router = new Router() 1. 定义接口前缀 router.prefix('/diary') 1. 定义接口 router.post('/login',()=>{}) 1. 让路由生效 把它抛出 module.exports ={ DiaryRouter:router } 并统一在一个地方(index.js)生效所有路由 const routerArr = [deepseekRouter,DiaryRouter] const useRouters = (app) =>{ routerArr.forEach(router =>{ app.use( router.routes(), router.allowedMethods() ) }) } 入口文件index.js: useRouters(app) # get vs post 1. get请求的参数是拼接在url后面的,而post请求的参数是放在请求体中的 2. 浏览器对get请求的参数的长度有限制,而post请求的参数的长度没有限制 # 防止xss攻击 const {verify} = require('../utils/jwt.js'); const {sanitizeComment} = require('../utils/xss.js'); 将用户提交的内容进行过滤