title: “对于字段未存的思考”
data: 2022.9.27
tag:
- 数据库
- 类型
字段未保存下来的思考
背景
- 项目在文件上传后的,无法进行下载
原因分析
-
检查发现后端返回的数据长度与上传不一致
-
后端数据库存储的数据是有大小限制的。
-
文件地址字段,在后台数据库mysql中设置的是512个字符。
-
前端通过OSS上传后拿到的是经过编码(encodeURI)后的地址。一个中文字符会被编译为9个普通字符。
-
因为用户上传时保留了上传的名字,就有可能使得超过512个字符,导致数据库存不下来
解决办法
-
oss上传的时候命名采用MD5,不保留原始文件名
-
弊端:下载的时候无法看到名称
-
oss上传的时候设置请求headers的’Content-Disposition’为’attachment;filename= encodeURI(文件名)';需要对中文名进行编码
-
下载的时候浏览器会读取这个字段的文件名进行下载
扩展
字节、字符和比特
-
acsll码下 1字符=1字节 存储的最大字符数256 2^8 不支持中文
-
Unicode码 1字符=2字节 存储的最大字符数65535 2^16 不兼容acsll
-
utf-8码下 1字符=3字节(汉字一般3字节;理论最长4字节) 兼容acsll(变长编码。所以可以兼容)
-
GBK 1个=2个字节(汉字一般为2字节;acsll字符为1字节)
- mysql一般用字符做单位
- 1字节=8bit
下载方式(四种)
- 上面那种通过设置OSS的header
- 地址栏直接打开。浏览不预览的直接下载,预览的 需要用户自己手动下载
- 请求文件地址,成功后将二进制文件读取为Blob,使用URL.createObjectURL生成Blob url,创建a链接模拟点击。存在兼容性问题、大文件体验不好
- a链接直接设置download。缺点:不支持跨域
// 第三种
fetch(url).then(res => {
res.blob().then(blob => {
const blobUrl = window.URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = blobUrl
a.download = name
a.click()
window.URL.revokeObjectURL(blobUrl)
})
})