完善消息发送函数,获取输入框里的所有子元素,找出base64图片将其转为文件并上传至服务器(此处需要注意:base64转文件时,需要用正则表达式删掉base64图片的前缀),将当前图片地址推送至websocket服务。
对下述代码有不理解的地方,可阅读我的另一篇文章:Vue实现图片与文字混输,
sendMessage: function (event) { if (event.keyCode === 13) { // 阻止编辑框默认生成div事件 event.preventDefault(); let msgText = ""; // 获取输入框下的所有子元素 let allNodes = event.target.childNodes; for (let item of allNodes) { // 判断当前元素是否为img元素 if (item.nodeName === "IMG") { if (item.alt === "") { // 是图片 let base64Img = item.src; // 删除base64图片的前缀 base64Img = base64Img.replace(/^data:image\/\w+;base64,/, ""); //随机文件名 let fileName = (new Date()).getTime() + ".jpeg"; //将base64转换成file let imgFile = this.convertBase64UrlToImgFile(base64Img, fileName, 'image/jpeg'); let formData = new FormData(); // 此处的file与后台取值时的属性一样,append时需要添加文件名,否则一直时blob formData.append('file', imgFile, fileName); // 将图片上传至服务器 this.$api.fileManageAPI.baseFileUpload(formData).then((res) => { const msgImgName = `/${res.fileName}/`; // 消息发送: 发送图片 this.$socket.sendObj({ msg: msgImgName, code: 0, username: this.$store.state.username, avatarSrc: this.$store.state.profilePicture, userID: this.$store.state.userID }); // 清空输入框中的内容 event.target.innerHTML = ""; }); } else { msgText += `/${item.alt}/`; } } else { // 获取text节点的值 if (item.nodeValue !== null) { msgText += item.nodeValue; } } } // 消息发送: 发送文字,为空则不发送 if (msgText.trim().length > 0) { this.$socket.sendObj({ msg: msgText, code: 0, username: this.$store.state.username, avatarSrc: this.$store.state.profilePicture, userID: this.$store.state.userID }); // 清空输入框中的内容 event.target.innerHTML = ""; } } }
base64图片转flie
// base64转file convertBase64UrlToImgFile: function (urlData, fileName, fileType) { // 转换为byte let bytes = window.atob(urlData); // 处理异常,将ascii码小于0的转换为大于0 let ab = new ArrayBuffer(bytes.length); let ia = new Int8Array(ab); for (let i = 0; i < bytes.length; i++) { ia[i] = bytes.charCodeAt(i); } // 转换成文件,添加文件的type,name,lastModifiedDate属性 let blob = new Blob([ab], {type: fileType}); blob.lastModifiedDate = new Date(); blob.name = fileName; return blob; } axios文件上传接口的封装(注意:需要设置"Content-Type":"multipart/form-data"}) /* * 文件管理接口 * */ import services from '../plugins/axios' import base from './base'; // 导入接口域名列表 const fileManageAPI = { // 单文件上传 baseFileUpload(file){ return services._axios.post(`${base.lkBaseURL}/uploads/singleFileUpload`,file,{headers:{"Content-Type":"multipart/form-data"}}); } }; export default fileManageAPI;
解析websocket推送的消息
// 消息解析 messageParsing: function (msgObj) { // 解析接口返回的数据并进行渲染 let separateReg = /(\/[^/]+\/)/g; let msgText = msgObj.msgText; let finalMsgText = ""; // 将符合条件的字符串放到数组里 const resultArray = msgText.match(separateReg); if (resultArray !== null) { for (let item of resultArray) { // 删除字符串中的/符号 item = item.replace(/\//g, ""); // 判断是否为图片: 后缀为.jpeg if(this.isImg(item)){ // 解析为img标签 const imgTag = `<img src="https://www.jb51.net/${base.lkBaseURL}/upload/image/${item}" alt="聊天图片">`; // 替换匹配的字符串为img标签:全局替换 msgText = msgText.replace(new RegExp(`/${item}/`, 'g'), imgTag); } } finalMsgText = msgText; } else { finalMsgText = msgText; } msgObj.msgText = finalMsgText; // 渲染页面 this.senderMessageList.push(msgObj); // 修改滚动条位置 this.$nextTick(function () { this.$refs.messagesContainer.scrollTop = this.$refs.messagesContainer.scrollHeight; }); }
判断当前字符串是否为有图片后缀
// 判断是否为图片 isImg: function (str) { let objReg = new RegExp("[.]+(jpg|jpeg|swf|gif)$", "gi"); return objReg.test(str); }
踩坑记录
直接将base64格式的图片通过websocket发送至服务端
结果很明显,服务端websocket服务报错,报错原因:内容超过最大长度。
前端通过post请求将base64码传到服务端,服务端直接将base64码解析为图片保存至服务器
从下午2点折腾到晚上6点,一直在找Java解析base64图片存到服务器的方案,最终选择了放弃,采用了前端转换方式,这里的问题大概是前端传base64码到后端时,http请求会进行转义,导致后端解析得到的base64码是错误的,所以一直没有成功。
项目地址:chat-system
总结
以上所述是小编给大家介绍的Vue解析剪切板图片并实现发送功能,希望对大家有所帮助!
您可能感兴趣的文章: