JS获取IMG标签中图片数据踩过的坑

3,314 阅读1分钟

** 项目需求,需要使用js获取当前页面某一个img标签中的图片数据,传给后台,需要兼容ie **

第一次尝试

最开始采用的是文件上传

代码:

  var FileController = "../../uploadServlet";
  var img = document.getElementById('imgSrc');
  var canvas = document.createElement('canvas');
  canvas.width = img.width;
  canvas.height = img.height;
  console.log('3000====', img, $('#imgSrc'))
  var ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0, img.width, img.height);
  var ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase();
  var dataURL = canvas.toDataURL('image/' + ext);
  var form = new FormData();
  var arr = dataURL.split(',')
  var mime = arr[0].match(/:(.*?);/)[1]
  var bstr = atob(arr[1])
  var n = bstr.length
  var u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  console.log('file:', new File([u8arr], 'filephoto.png', { type: mime }))
  form.append("file", new File([u8arr], 'filephoto.png', { type: mime }));// 文件对象
  // XMLHttpRequest 对象
  var xhr = new XMLHttpRequest();
  xhr.open("post", FileController, true);
  xhr.onload = function () {
    if (xhr.responseText != "0") {
      console.log(JSON.parse(xhr.responseText).fileRelativePath)
      window.INSERT_FLOW_IMG_FILE_PATH = JSON.parse(xhr.responseText).fileRelativePath
      passAnychat(val)
      console.log('保存成功');
    } else {
      console.log("上传失败");
      return;
    }
  };
  xhr.send(form);

这段代码在chrome上没有问题,但是在ie上报错,因为ie不支持new File()

因此决定修改为使用base64格式数据上传

第二次尝试

代码:

var FileController = "../../uploadServlet";
  var img = document.getElementById('imgSrc');
  var canvas = document.createElement('canvas');
  canvas.width = img.width;
  canvas.height = img.height;
  console.log('3000====', img, $('#imgSrc'))
  var ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0, img.width, img.height);
  var ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase();
  var dataURL = canvas.toDataURL('image/' + ext);
  ajaxRequest({
		async : false,
		req : [ {
			service : 'uploadImgToFileService',
			filter_error : false,
			IMG_BASE64 : encodeURIComponent(dataURL.substring(dataURL.indexOf(';base64,') + 8)),
			FLOW_NO : window.clientUser[3] || '',
			IMG_CLS : '021'
		} ],
		error : function(data) {
			alert("上传大头照失败");
			console.log("上传大头照失败");
		},
		func : function(data) {
			console.log(data, data[0][0].IMG_URL)
			window.INSERT_FLOW_IMG_FILE_PATH = data[0][0].IMG_URL
			passAnychat(val)
			console.log('保存成功');
		}
  });

在开发环境当前代码已经没有问题,ie也能通过

问题发生在测试环境上,测试环境分为内网环境外网环境

在外网环境下没有问题,内网环境报canvas.toDataURL跨域的问题

采用网上的方法,给img标签增加一个属性crossorigin="anonymous",但是没有解决问题

此时想到了另外一个方法

第三次尝试

使用xhr去获取img.src的内容,可以得到arraybuffer数据

	var xmlHttp = new XMLHttpRequest()
	xmlHttp.open("GET", src, true)
	xmlHttp.responseType = "arraybuffer"
	xmlHttp.onload = function (e) {
		console.log('load:', xmlHttp.response)
		var arr = new Uint8Array(xmlHttp.response)
		var i = arr.length;
        var binaryString = new Array(i);
        while (i--) {
          binaryString[i] = String.fromCharCode(arr[i]);
        }
        var data = binaryString.join('');
        var base64 = window.btoa(data);
        var dataUrl = "data:image/png" + ";base64," + base64
		$("#reverse_img").attr("src", dataUrl)
	}
	xmlHttp.onerror = function (err) {
		console.log('xmlHttp.onerror')
	}
	xmlHttp.send()

此时ie报错XMLHttpRequest: 网络错误 0x80700013

本人电脑通过调低本地网络安全等级解决了,但是同事的电脑调低后还是报错

最后

以上的方法其实都可以做到要求的效果,但是对ie的支持都不好,谨慎使用