首页
关于
留言
壁纸
更多
直播
统计
友链
Search
1
最新Navicat 15 for MySQL破解+教程 正确破解步骤
191 阅读
2
面试常见问题100问
190 阅读
3
一个人要走的时候,千万别问原因
162 阅读
4
好用的软件分享
160 阅读
5
直击心灵的唯美句子
121 阅读
日常记录
后端
PHP
NodeJs
Python
Java
前端
JavaScript
数据库
MySQL
服务器
美文
微信开发
微信公众号
微信小程序
登录
Search
标签搜索
mysql
python
django
express
面试
axios
thinkphp
PHP
励志
哲理
九九乘法表
node
cors
跨域
唯美句子
美文
文件上传
ajax
算法
jwt
公子初心
累计撰写
68
篇文章
累计收到
9
条评论
首页
栏目
日常记录
后端
PHP
NodeJs
Python
Java
前端
JavaScript
数据库
MySQL
服务器
美文
微信开发
微信公众号
微信小程序
页面
关于
留言
壁纸
直播
统计
友链
搜索到
6
篇与
的结果
2024-03-21
npm安装webpack时遇到卡顿的情况
npm安装webpack时遇到卡顿的情况idealTree:webpackdemo: sill idealTree buildDeps解决办法:删除npmsrc 清除缓存 命令行找到其所在位置,删除此文件 npm config get userconfig清除缓存 npm cache clear --force有可能是之前的镜像源停止解析了,所有要更换最新的 npm config set registry https://registry.npmmirror.com查看当前镜像源确保更换成功npm config get registry重新安装npm i webpack webpack-cli --sav-dev
2024年03月21日
28 阅读
0 评论
0 点赞
2023-07-19
express配合JWT身份验证
1. 什么是JWTJWT(英文全称:JSON Web Token)是目前最流行的跨域认证解决方案2. JWT的工作原理总结:用户的信息通过Token字符串的形式,保存在客户端浏览器中。服务器通过还原Token字符串的形式来认证用户的身份3. JWT的组成部分JWT 通常由三部分组成,分别是 Header(头部)、Payload(有效荷载)、Signature(签名)。三者之间使用英文的“.”分隔,格式如下:下面是 JWT 字符串的示例:4. JWT的三个部分各自代表的含义JWT 的三个组成部分,从前到后分别是 Header、Payload、Signature。其中:Payload 部分才是真正的用户信息,它是用户信息经过加密之后生成的字符串。Header 和 Signature 是安全性相关的部分,只是为了保证 Token 的安全性。5. JWT 的使用方式客户端收到服务器返回的 JWT 之后,通常会将它储存在 localStorage 或 sessionStorage 中。此后,客户端每次与服务器通信,都要带上这个 JWT 的字符串,从而进行身份认证。推荐的做法是把 JWT 放在 HTTP 请求头的 Authorization 字段中,格式如下:5.1 安装JWT相关的包jsonwebtoken 用于生成 JWT 字符串express-jwt 用于将 JWT 字符串解析还原成 JSON 对象5.2 创建jwt小项目 初始化基本的路由请求app.js// 主程序 const express = require("express") // 导入express // 解决跨域问题 const cors = require("cors") const app = express() // 实例化app对象 app.use(express.urlencoded({extended:false}))// 接收post表单数据 app.use(cors()) // 解决跨域问题 app.get('/',(req,res)=>{ res.send("ok") }) app.listen(80,()=>{ console.log("express service is running at http://127.0.0.1") })5.3 创建登录路由,请求方式为post,如果登录失败则返回router.post("/login",(req,res)=>{ // 将req.body 请求体中的数据转存为userinfo常量 const userinfo = req.body if(userinfo.username != 'admin' || userinfo.password != '000000'){ return res.send({ status:400, message:'登录失败' }) } })5.4 导入JWT相关的包使用 require() 函数,分别导入 JWT 相关的两个包:const jwt = require("jsonwebtoken") const expressJWT = require("express-jwt")5.5 定义secret密钥为了保证 JWT 字符串的安全性,防止 JWT 字符串在网络传输过程中被别人破解,我们需要专门定义一个用于加密和解密的 secret 密钥:当生成 JWT 字符串的时候,需要使用 secret 密钥对用户的信息进行加密,最终得到加密好的 JWT 字符串当把 JWT 字符串解析还原成 JSON 对象的时候,需要使用 secret 密钥进行解密// 定义secret密钥 本质就是一个字符串用于加密和解密 const secretKey = "itnan.cc"5.6 登录成功后的代码router.post("/login",(req,res)=>{ // 将req.body 请求体中的数据转存为userinfo常量 const userinfo = req.body if(userinfo.username != 'admin' || userinfo.password != '000000'){ return res.send({ status:400, message:'登录失败' }) } // 如果登录成功 调用jwt.sign()方法生成jwt字符串,通过token发送给客户端 // 参数1:用户的信息对象,你想存储的用户信息 // 参数2:加密的密钥 // 参数3:配置对象,可以配置当前token的有效期 const tokenStr = jwt.sign({username:userinfo.username},secretKey,{expiresIn:'60s'}) res.send({ status:200, message:"登录成功", token:tokenStr }) })5.7 发送请求测试token是否可以生成如果登录失败(用户名或者密码不正确)5.8 将 JWT 字符串还原为 JSON 对象客户端每次在访问那些有权限接口的时候,都需要主动通过请求头中的 Authorization 字段,将 Token 字符串发送到服务器进行身份认证。此时,服务器可以通过 express-jwt 这个中间件,自动将客户端发送过来的 Token 解析还原成 JSON 对象:// 使用app.use()注册中间件 // express.JWT({secret:secretKey}) //用来解析Token的中间件 // .unless({path:[/^\/api\//]}) 用来指定哪些接口不需要访问权限 app.use(expressJWT({"secret":secretKey})).unless({path:[/^\/api\//]}) )换种写法完美解决问题app.use(expressJWT.expressjwt({secret:secretKey,algorithms:["HS256"]}).unless({path:[/^\/api\//]}))5.9 定义登录成功后获取用户信息的路由// 获取用户信息 需要用户登录成功后才可以 app.post("/getinfo",(req,res)=>{ // 使用req.auth 获取用户信息,使用data属性将用户信息发送给客户端 res.send({ status:200, message:"获取用户信息成功", data:req.auth }) })5.10 postman测试登录成功后获取用户信息需要在header头信息中加上Authorization 值是 Bearer token信息5.11 捕获解析JWT失败后产生的错误(过期了)当使用 express-jwt 解析 Token 字符串时,如果客户端发送过来的 Token 字符串过期或不合法,会产生一个解析失败的错误,影响项目的正常运行。我们可以通过 Express 的错误中间件,捕获这个错误并进行相关的处理,示例代码如下:定义一个中间件 用于处理token过期的情况 这个中间件需要定义在所有路由之后其实捕获的就是UnauthorizedError这个错误类型// 捕获解析JWT失败后产生的错误 app.use((err,req,res,next)=>{ // token解析失败导致的错误 if(err.name === 'UnauthorizedError' ){ return res.send({status:401,message:'无效token'}) } // 其他原因导致错误 return res.send({status:500,message:'未知错误'}) })附源码: 源码下载
2023年07月19日
34 阅读
0 评论
0 点赞
2023-07-18
express操作mysql数据库实现增删改查
1. 引入mysql模块并连接数据库// 引入mysql模块 const mysql = require("mysql") // 连接数据库 const db = mysql.createPool({ host:'127.0.0.1', user:'root', password:'root', database:'test' })2.测试连接// 测试连接 db.query("select 1",(err,result)=>{ if(err) return console.log(err.message) console.log(result); })3.查询所有数据// 查询所有数据 let sql = "select * from stu " db.query(sql,(err,result)=>{ if(err) return console.log(err.message) console.log(result); })4. 根据条件查询数据// 根据条件查询数据 let sql = "select * from stu where id = ? " let params = {id:1} db.query(sql,[params.id],(err,result)=>{ if(err) return console.log(err.message) console.log(result); })5. 添加数据 (添加指定字段)根据受影响的行数来判断是否添加成功// 添加数据 let sql = "insert into stu (username,age) values(?,?) " let params = {username:"老李",age:21} db.query(sql,[params.username,params.age],(err,result)=>{ if(err) return console.log(err.message) if (result.affectedRows === 1) console.log("添加成功"); })6. 添加的便捷方式(如果添加的是所有字段)let sql = "insert into stu set ? " let params = {id:null,username:"老白",age:22} db.query(sql,params,(err,result)=>{ if(err) return console.log(err.message) if (result.affectedRows === 1) console.log("添加成功"); })7. 修改let sql = "update stu set username = '大明' where id = ? " let params = {id:1} db.query(sql,[params.id],(err,result)=>{ if(err) return console.log(err.message) if (result.affectedRows === 1) console.log("修改成功"); })8.修改的便捷方式 多个条件可以放到一个对象中let sql = "update stu set ? where id = ? " let params = {username:'小王'} db.query(sql,[params,2],(err,result)=>{ if(err) return console.log(err.message) if (result.affectedRows === 1) console.log("修改成功"); })9. 删除let sql = "delete from stu where id = ? " let params = {id:1} db.query(sql,[params.id],(err,result)=>{ if(err) return console.log(err.message) if (result.affectedRows === 1) console.log("删除成功"); })
2023年07月18日
19 阅读
0 评论
0 点赞
2023-07-17
express路由
1.简单路由示例const express = require('express') const app = express() app.get('/',(req,res)=>{ res.send("hello") }) app.listen(80,()=>{ console.log("http://127.0.0.1") })2.路由模块示例主程序const express = require('express') const router = require('./route') const app = express() app.use(router) app.listen(80,()=>{ console.log("http://127.0.0.1") })路由模块route.jsconst express = require("express") const router = express.Router() router.get('/',(req,res)=>{ res.send("hello router") }) module.exports = router
2023年07月17日
13 阅读
0 评论
0 点赞
2022-09-21
express解决跨域问题
1.原始方式app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*') res.header('Access-Control-Allow-Headers', 'Authorization,X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method' ) res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PATCH, PUT, DELETE') res.header('Allow', 'GET, POST, PATCH, OPTIONS, PUT, DELETE') next(); });2.express使用cors来解决跨域问题2.1 js主程序// 1.使用npm安装cors npm -i cors // 2.引入cors模块 // 3.在路由之前配置cors中间件解决跨域问题 const express = require('express') const router = require('./route') const qs = require("querystring") const app = express() const cors = require("cors") app.use(express.urlencoded({extended:false})) app.use(express.json()) app.use(cors()) app.use(router) app.listen(80,()=>{ console.log("http://127.0.0.1") })2.2 路由模块 const express = require("express") const router = express.Router() router.get('/',(req,res)=>{ console.log(req.query); res.send(req.query) }) router.post('/',(req,res)=>{ console.log(req.body); res.send(req.body) }) module.exports = router2.3 前端使用axios发起get,post请求<!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="axios.js"></script> </head> <body> <button id="btnGet">get请求</button> <button id="btnPost">post请求</button> <script> let btnGet = document.querySelector("#btnGet") let btnPost = document.querySelector("#btnPost") btnGet.addEventListener("click",()=>{ axios.get("http://127.0.0.1",{ params:{ id:123, name:'hello' } }).then(res=>{ console.log(res.data); }); }) btnPost.addEventListener("click",()=>{[ axios.post('http://127.0.0.1', {id:1,name:"laobai"}) .then(function(ret){ console.log(ret.data) }) ]}) </script> </body> </html>
2022年09月21日
53 阅读
0 评论
0 点赞
2022-09-14
使用formidable模块上传文件的一些问题
本文介绍formidable模块保留上传文件的扩展名问题(有可能上传文件成功后无法保存文件扩展名)当前的版本为"formidable": "^2.0.1",{dotted startColor="#ff6c6c" endColor="#1989fa"/}前端代码: <div class="form-group"> <label for="exampleInputFile">文章封面</label> <input type="file" name="file" id="file"> <div class="thumbnail-waper"> <img class="img-thumbnail" src="" id="thumb" width="100"> </div> </div>服务器端代码:{dotted startColor="#ff6c6c" endColor="#1989fa"/}// 引入formidable模块 const formidable = require('formidable'); // 引入路径模块 const path = require('path'); // 第三种写法需要引入这个 const {IncomingForm} = require('formidable'); module.exports = (req, res) => { //1.第一种写法 const form = new formidable.IncomingForm(); form.multiples = true, // 设置上传文件的保存路径 form.uploadDir = path.join(__dirname,'public','uploads'); // 保留原来文件扩展名 测试没有生效 form.keepExtensions = true; // 2.第二种写法 const form = formidable({ multiples:true, uploadDir: path.join(__dirname, "../", "../", 'public', 'uploads'), keepExtensions: true }) // 3.第三种写法 const form = IncomingForm({ multiples:true, uploadDir: path.join(__dirname, "../", "../", 'public', 'uploads'), keepExtensions: true }) form.parse(req,(err,fields,files)=>{}) }第二种,第三种都可以保留文件扩展名图片上传的预览效果:{dotted startColor="#ff6c6c" endColor="#1989fa"/} var file = document.querySelector('#file'); file.onchange = function(){ // 1.创建文件读取对象 var reader = new FileReader(); // 2.读取文件 reader.readAsDataURL(this.files[0]) console.log(this.files[0]); // 3.监听onload事件 reader.onload = function(){ console.log(reader.result); $('#thumb').attr('src',reader.result) } }
2022年09月14日
47 阅读
0 评论
0 点赞