毕设其中有一个需求,就是前端需要上传图片。
周末就写一下小测试代码。
其中遇到一些奇奇怪怪的bug,虽然是周末遇到的,还是要记录一下。
数据库表
def create_table(self):
sql = """CREATE TABLE %s (
`idpic` int(11) NOT NULL auto_increment,
`caption` varchar(45) NOT NULL default '',
`img` mediumblob NOT NULL,
PRIMARY KEY (`idpic`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;""" % self.table
return self.db.cursor().execute(sql)
首先,后端给向数据库导入图片的字节码。
疑惑1
这样导入数据可以
sql = """insert into test1 values(%s,%s,%s);""" % ("1", "11", "111")
self.db.cursor().execute(sql)
而这样导入数据不行
sql = """insert into test1 values(%s,%s,%s);""" % ("1", "11", img)
self.db.cursor().execute(sql)
上面两种导入格式不是一模一样吗??????奇了怪了
而这样导入数据它又行了
sql = """insert into test1 values(%s,%s,%s);"""
args = ("1", "11", img)
self.db.cursor().execute(sql, args)
疑惑二
自己编码的问题,数据类的文件名和类名相同,而且该文件写了测试代码,启动端口服务。
然而,导入数据库类文件时,实例化了改文件,它就启动服务了。导致在服务文件启动的服务被覆盖,请求服务文件里写的一些接口,一直提示存在跨域。然而,这是前后端分离的,后端一直开放的,不可能存在跨域问题,而且修改了后端可以请求的接口的返回值,但是前端获取到的返回值一直没变,我怀疑是缓存问题,把浏览器的缓存清空,返回值还是没变,那么关机重启好吧,但是重启也不行。各种找解决办法,各种尝试,百思不得其解。最终,也不知道怎么就打开了数据库类文件,才发现这里竟然还有测试代码,果断删掉,再次测试,额,它终于行了。这折腾了大半天了,,,,,kao。。。。。
以下是前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<button>getImg</button>
<input type="file" id="file">
<img id="img" src="" style="display: block;width: 60%;">
<script>
const btns = document.getElementsByTagName("button")
const getImg = btns[0]
// axios方式
// getImg.onclick = ()=>{
// axios({
// url:"http://localhost:8888/test",
// method:"get",
// responseType:"blob",
// }).then(
// result=>{
// const blog = new Blob([result.data],{type:"image/jpeg"});
// const url = window.URL.createObjectURL(blog);
// const img = document.getElementById("im");
// img.src = url;
// }
// )
// }
getImg.onclick = function(){
// 1.创建对象
const xrp = new XMLHttpRequest();
xrp.open("GET","http://localhost:8888/test")
xrp.responseType = "blob"
xrp.send()
xrp.onreadystatechange = function(){
if(xrp.readyState === 4){
if(xrp.status >=200 && xrp.status < 300){
// 拿到响应体的二进制流数据,并转换成图片。
// 实际上,后端传回来的是在云端的url,把该url直接给img即可,
// 不需要在本地把传回来的二进制流转化成图片,再给图片创建一个url
const blob = new Blob([xrp.response],{type:"image/jpeg"});
// 创建一个本地的url,
const url = window.URL.createObjectURL(blob);
// 获取img
const img = document.getElementById("img");
// 给img的src 赋值为本地的url
img.src = url;
}
else{
console.log("fuck, error again!!!")
}
}
}
}
// 上传函数
function upload(binary){
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:8888/test1");
xhr.overrideMimeType("application/octet-stream");
//直接发送二进制数据
if(xhr.sendAsBinary){
xhr.sendAsBinary(binary);
}else{
xhr.send(binary);
}
// 监听变化
xhr.onreadystatechange = function(e){
if(xhr.readyState===4){
if(xhr.status===200){
// 响应成功
}
}
}
}
// 前端获取二进制数据流,发送给后端
const input = document.querySelector('input[id="file"]')
// 监听事件
input.addEventListener('change', ()=>{
const reader = new FileReader()
reader.readAsArrayBuffer(input.files[0]) // input.files[0]为第一个文件
reader.onload = ()=>{
console.log(reader.result)
upload(reader.result)
}
}, false)
</script>
</body>
</html>