说明:后端(node)、前端(vue)
一、因base64字符串过长报500的问题:
数据库:表中存图片的字段类型为mediumtext或text
当上传的图片小(base64字符串长度小)时,发请求成功
当上传的图片大(base64字符串长度过长)时,发请求失败,接口报500。
原因:不是post请求限制请求数据的大小,是被后端服务器限制了。
解决:在app.js中注册中间件,一定要在路由前注册,否则无效
app.use(bodyParser.json({limit:'600mb'})); //解决请求体过大传不过来的问题
app.use(bodyParser.urlencoded({ limit:'600mb'}))
注:上传过大的图片还可能会有个问题(执行SQL时报的错,一般会以响应体的形式返回给前端,大概意思是字符串过长)--字符串过长,原因是数据表中存图片的字段长度不够,把字段类型text改成mediumtext类型即可。
二、以form-data格式传数据给后端,掉参数(后端接收不到)问题
开始我一直想不通,用postman可以正常发请求,而且参数也全部发过去了,但前端发请求时,看请求体也有file参数(保存base64字符串的参数),但接口的响应中说没有file这个参数。后来打印后端请求体发现没有file参数。-------后端收不到保存base64字符串的参数
原因:后端接收的图片的参数值应该是一个文件对象,而不是base64字符串。
因为后端用了multer包解析form-data格式表单数据,部分代码如下:
const express = require('express')
const router = express.Router()
// 导入验证数据的中间件
const expressJOI = require('@escook/express-joi')
const article_schema = require('../schema/article')
// 导入解析 formdata 格式表单数据的包
const multer = require('multer')
// 导入处理路径的核心模块
const path = require('path')
// 创建 multer 的实例对象,通过 dest 属性指定文件的存放路径
const upload = multer({ dest: path.join(__dirname, '../uploads') })
const article_handler = require('../router_handler/article')
// upload.single() 是一个局部生效的中间件,用来解析 FormData 格式的表单数据
// 将文件类型的数据,解析并挂载到 req.file 属性中
// 将文本类型的数据,解析并挂载到 req.body 属性中
// ------------------------先解析------------------------后验证
router.post('/pubarticle', upload.single('file'), expressJOI(article_schema.pub_article_rule), article_handler.pubArticle)
module.exports = router
pubArticle: (req, res) => {
// 手动判断是否上传了文章封面----req.file.fieldname的值就是你传过来的请求体内的参数名
if (!req.file || req.file.fieldname !== 'file') return res.cc('文章封面是必选参数!')
}
实际原因是后端已经接收到了这个file参数,是因为代码执行到 if (!req.file || req.file.fieldname !== 'file') return res.cc('文章封面是必选参数!') 就直接响应给前端了。
传到数据库的是这样一个字符串:\uploads\25d1551253efa778d5036a83330a015a
前端下次请求会直接由服务器加工传过去。
这里再说在前端页面上传图片后想预览图片的问题,<img src="" />,src里应该放base64字符串,而不是文件对象或者文件对象里的文件名,否则无法预览。还有src不能绑定一个图片的相对路径字符串,如果想绑定,只能用 import imgObj from '../../assets/pic1.png' 的形式导入,再把imgObj赋给src属性。