angular实现IM聊天图片发送实例


Posted in Javascript onMay 08, 2017

IM聊天图片发送有两种方式

  1. 截图粘贴到信息框后点击发送
  2. 选择本地图片发送

图片剪切粘贴,使用QQ或者其他平台的截图功能,截图后粘贴 Ctrl+V ,这个过程需要获取粘贴板上的图片数据,并在页面中展示,也就是将图片数据创建一个img元素,就可以显示出来了。

从粘贴面板中获取图片数据

/**
 * 黏贴发送图片
 * @param e
 */
pasteData(e) {
  e.preventDefault();
  let clipboardData = e.clipboardData;
  if (clipboardData) { //如果支持这个
    let items = clipboardData.items; //获取黏贴里的对象
    if (!items) {
      return;
    }
    let item;
    let types = clipboardData.types || [];
    for (let i = 0, len = types.length; i< len; i++) {
      if (types[i] === 'Files') {
        item = items[i];
        break;
      }
    }
    if (item && item.kind === 'file' && item.type.match(/^image\//i)) {
      imgReader(item);
    }
  }
  functionimgReader(obj){
   let $messageBox=$('#message-boxID');
    let file = obj.getAsFile(),
      reader = new FileReader();
    // 读取文件
    reader.readAsDataURL(file);
    reader.onload = function(e){
      let img = new Image();
      img.src = e.target['result'];
      img.className = 'chatImg';

      $messageBox.append(img);
      setTimeout(()=> {
        $messageBox.scrollTop($messageBox[0].scrollHeight);
      }, 0)
    };
  }
}

本地图片选择

<inputid="upImg"name="fileTrans"type="file"(change)="onFileSelect($event)"/>
/**
 * 选择图片
 * @param event
 */
files:any[]=[];
onFileSelect(event) {
  this.files=[];
  let files = event.dataTransfer ? event.dataTransfer.files : event.target.files;
  let file;
  for (let i = 0; i < files.length; i++) {
    file = files[i];
    if (this.isImage(file)) {
      file.objectURL = this.sanitizer.bypassSecurityTrustUrl((window.URL.createObjectURL(files[i])));
      this.files.push(files[i]);
    }
  }
  let fileUrl = file.objectURL.changingThisBreaksApplicationSecurity;
  let img = new Image();
  img.src = fileUrl;
  img.className = 'chatImg';

  $('#message-boxID').append(img);
}

图片上传服务器

前端angular上传图片到服务器,必然是ajax请求的方式,将图片数据转成二进制流传给后端了。

url:string="http://localhost:8080/upload";
progress:number=0;//进度

uploadPic(formData):Promise<any> {
   let xhr = new XMLHttpRequest(),
   
   
   //封装xhr请求
   return new Pormise(resolve,reject){
     xhr.upload.addEventListener('progress', (e: ProgressEvent) => {
     if(e.lengthComputable) {
      this.progress = Math.round((e.loaded * 100) / e.total);
     }
     }, false);

     xhr.onreadystatechange = ()=> {
       if(xhr.readyState == 4) {
         this.progress = 0;
         
         if(xhr.status >= 200 && xhr.status < 300)
           resolve({xhr: xhr, files: this.files});
         else
           reject({xhr: xhr, files: this.files});
       }
     };
     
     xhr.open('POST', this.url, true);
     //jwt后端验证,设置请求头部信息,解决跨域
     xhr.setRequestHeader("Authorization", "Basic " + localStorage.getItem('jwt'));
     
     xhr.send(formData);
   }
 }

将以上方法写到一个 upload-file.servie.ts 中。然后其他地方就可以使用 uploadFileService.uploadPic() 方法调用了。

这里后端代码忽略,后端Java或者nodejs都很简单,接收文件二进制流保存,或者是上传到百度云与阿里云。

信息发送按钮处理

发送信息处理,需要处理好文本信息和图片信息两种。

/**
 * dataURL to blob, ref to https://gist.github.com/fupslot/5015897
 * @param dataURI
 * @returns {Blob}
 */
functiondataURItoBlob(dataURI){
  var byteString = atob(dataURI.split(',')[1]);
  var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
  var ab = new ArrayBuffer(byteString.length);
  var ia = new Uint8Array(ab);
  for (var i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
  }
  return new Blob([ab], {type: mimeString});
}

/**
   * 发送消息
   * @param taskValue
   */
  sendMessage() {
    let dateTime = this.dateFromat.FormatDate(new Date());
    let value = $('#message-boxID').html();
    let isImg = value.includes('<img');
    //如果是图片信息
    if (isImg) {
      let formData = new FormData();
      let dataURL="";
      let src=$(value)[0].src;
      //图片截图粘贴
      if(src.includes('data:images')){
        dataURL=src;
        let blob = dataURItoBlob(dataURL);
        formData.append('file', blob);
      
      //图片本地选择
      }else if(src.includes('blob:http')){
         //files是图片选择时保存的图片文件对象,见onFileSelect方法
        for(let i = 0; i < this.files.length; i++) {
          formData.append('file', this.files[i], this.files[i].name);
        }
      }
      //调用上传图片方法
      this.uploadFileService.uploadPic(formData).then(result=>{
        //上传成功,do something
        console.log(result);
        
      }).catch(err=>{
        console.log('图片上传失败'+err);
      })
    }else{
      //非图片信息,文本发送
      //this.submitMessage(value);
    }

  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用javascript实现的支持lrc歌词的播放器
May 17 Javascript
jQuery EasyUI API 中文文档 - Form表单
Oct 06 Javascript
吐槽一下我所了解的Node.js
Oct 08 Javascript
js过滤HTML标签完整实例
Nov 26 Javascript
javascript嵌套函数和在函数内调用外部函数的区别分析
Jan 31 Javascript
深入理解JS中的substr和substring
Apr 26 Javascript
javascript实现滚动效果的数字时钟实例
Jul 21 Javascript
前端程序员必须知道的高性能Javascript知识
Aug 24 Javascript
EasyUI框架 使用Ajax提交注册信息的实现代码
Sep 27 Javascript
详解Vue项目编译后部署在非网站根目录的解决方案
Apr 26 Javascript
浅谈Webpack下多环境配置的思路
Jun 27 Javascript
vue实现井字棋游戏
Sep 29 Javascript
Angular.Js中过滤器filter与自定义过滤器filter实例详解
May 08 #Javascript
canvas简单快速的实现知乎登录页背景效果
May 08 #Javascript
详解JavaScript中return的用法
May 08 #Javascript
如何使用angularJs
May 08 #Javascript
关于foreach循环中遇到的问题小结
May 08 #Javascript
js下载文件并修改文件名
May 08 #Javascript
JS将unicode码转中文方法
May 08 #Javascript
You might like
php str_pad 函数用法简介
2009/07/11 PHP
浅析php过滤html字符串,防止SQL注入的方法
2013/07/02 PHP
php+js实现异步图片上传实例分享
2014/06/02 PHP
一个判断email合法性的函数[非正则]
2008/12/09 Javascript
js 屏蔽鼠标右键脚本附破解方法
2009/12/03 Javascript
web前端开发也需要日志
2010/12/09 Javascript
Jquery 表格合并的问题分享
2011/09/17 Javascript
15条JavaScript最佳实践小结
2013/08/09 Javascript
jquery通过select列表选择框对表格数据进行过滤示例
2014/05/07 Javascript
jquery操作checkbox示例分享
2014/07/21 Javascript
JavaScript实现为input与textarea自定义hover,focus效果的方法
2015/08/21 Javascript
JS弹出层遮罩,隐藏背景页面滚动条细节优化分析
2016/04/29 Javascript
jQuery简单实现title提示效果示例
2016/08/01 Javascript
vue+vuex+axios+echarts画一个动态更新的中国地图的方法
2017/12/19 Javascript
nginx部署访问vue-cli搭建的项目的方法
2018/02/12 Javascript
vue框架搭建之axios使用教程
2018/07/11 Javascript
对vue2.0中.vue文件页面跳转之.$router.push的用法详解
2018/08/24 Javascript
nodejs aes 加解密实例
2018/10/10 NodeJs
[07:39]第一届亚洲邀请赛回顾视频
2017/02/14 DOTA
Python实现给qq邮箱发送邮件的方法
2015/05/28 Python
tensorflow更改变量的值实例
2018/07/30 Python
Python计算不规则图形面积算法实现解析
2019/11/22 Python
Python无头爬虫下载文件的实现
2020/04/02 Python
在ipython notebook中使用argparse方式
2020/04/20 Python
详解matplotlib中pyplot和面向对象两种绘图模式之间的关系
2021/01/22 Python
美国网上书店:Barnes & Noble
2018/08/15 全球购物
屈臣氏乌克兰:Watsons UA
2019/10/29 全球购物
施惠特软件测试面试题以及笔试题
2015/05/13 面试题
2014国培学习感言
2014/03/05 职场文书
安全承诺书范文
2014/03/26 职场文书
电子装配专业毕业生求职信
2014/04/23 职场文书
商务专员岗位职责范本
2014/06/29 职场文书
电子工程求职信
2014/07/17 职场文书
交通事故被告代理词
2015/05/23 职场文书
感恩主题班会教案
2015/08/12 职场文书
《绝招》教学反思
2016/02/20 职场文书