好久没有编程了,最近需要完成一个小功能,为了方便,需要粘贴图片后上传到后台。前台编辑器用tinymce(N年前用过,我也就知道这个编辑器而已。这次使用下来感觉文档更丰富了),后台我用的Flask。昨天从下午4点开始一直捣鼓到半夜2点,终于完成了,这里大致记录一下遇到的问题和解决的办法。

1.  使用的tinymce版本是4.7.4,稍微熟悉了一下,advlist 插件不能用。 粘贴图片主要用的是自带的paste插件。

 tinymce.init({
selector:'#mycontent',
menubar:false,
plugins: [
'code paste',
],
toolbar:'code',
height:400,
paste_data_images: true
});

2. 上面的代码已经能成功粘贴图片,并且显示在编辑框里面了。我查看了源代码,图片的src是这样的

<img src="blob:http://127.0.0.1:5000/e8b7743b-6637-45f5-8473-9cf5271cc841">

3. 我懵逼了,这是什么玩意儿,但是似乎听说过Blob这个东西。我又想了下我的思路,我是要把这个图像上传到后台,然后把后台的地址返回给客户端,然后把这个src给替换掉。 因此我的问题就是把这个图片读出来,然后上传。一开始我网上找到不少解决方法,可以把blob读出来,主要是用了HTML5的canvas 对象。用context 画图,然后输出DataURL,转化为Base64。 这一段耗费了我大量的时间。 下面的代码是有问题的,贴出来仅仅是为了表达完整的过程。

var Img = new Image();
Img.src=url;
width = Img.width; // 实际上是拿不到长宽的。
height = Img.height;
var canvas = document.createElement("canvas");
canvas.getContext("2d").drawImage(Img,0,0, width, height);
dataURL=canvas.toDataURL('image/jpeg');

 大致的核心代码如上。rul: 就是上面 blob:http://.... 这一段。关键在于drawImage这个函数上,我为了看看这个画布上画出来的图像是否跟我粘贴的图像是一样的,因此在页面下部让这个画布显示出来,我遇到了几个问题

1. 第一次粘贴,画布无法显示图像,第二次粘贴后,画布会一次显示2个图像,而且错误 -__-!

2. 画布大小和图像大小不匹配。 打印了width和height 之后发现都是0。原来blob图像无法获得长宽。

3. 我粘贴的图像比较大,1800×3600以上,Base64太长了,传到后台,保存成图像之后,数据丢失,出来的是一片白色。

因此这条路基本上是走不通了。

4. 解决方法:换成纯二进制数据进行操作,不再转换。

直接看下面的代码吧,写的很粗,因为我不是很懂javascript。基本上全是复制粘贴过来的。

<script>

    globalcounter = 1;

    tinymce.init({
selector:'#mycontent',
menubar:false,
plugins: [
'code paste',
],
toolbar:'code',
height:400,
paste_data_images: true,
paste_preprocess: function(plugin, args) {
args.content = args.content.replace("<img", "<img id=\"pasted_image_" + parseInt(globalcounter) + "\"");
console.log(args.content)
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200){ upload(this.response);
}
}; xhr.open('GET', args.content.split('"')[3]);
xhr.responseType = 'blob';
xhr.send(); function upload(BlobFile){
var x = new XMLHttpRequest();
x.onreadystatechange = function(){
if( this.readyState == 4 && this.status == 200 ){
data = this.responseText;
console.log('response data: ' + data);
id = parseInt(globalcounter++); // function setimg(id, data){
// if( document.getElementById("pasted_image_" + id) == null){
// setTimeout( setimg , 5000);
// }else{
// document.getElementById("pasted_image_" + id).setAttribute("src", data);
// }
// }
document.getElementById("mycontent_ifr").contentWindow.document.getElementById("pasted_image_" + id).setAttribute("src", data);
}
};
x.open('POST', '/pasteimg/');
x.send(BlobFile);
} } });
</script>  

这里是后台的python代码,框架用的是Flask

@app.route('/pasteimg/', methods=['GET','POST'])
def paste_upload():
if request.method == 'POST':
imgdata = request.get_data()
file = open('test.png', 'wb')
file.write(imgdata)
file.close() imgsrc = "/static/img/60_1.png"
return Response( imgsrc, mimetype='application/text')

  

上面的代码有几个我遇到的问题,解决了。也有一些问题,我只是绕过了,但是没有真正解决;:

1. 用XMLHttpRequest 可以直接把img 读出来成为一段二进制数据 -- blob。而且没有大小限制,我贴的图片有时候size超过7位数。。也能够顺利上传到后台,相比之下,我觉得比Base64一串常常的字符串好多了。

2. tinymce 的paste_postprocess 中无法给插入对象设置id,这样我之后就没有办法获取图片了,因此,我只能在preprocess中设置了id,由于要插入多张图片,因此我用一个全局的计数器来递增id号。以后如果有多个textarea,那么还要再想办法。

3. jquery 的ajax方法不能传二进制,因此用XMLHttpRequest.

4. XMLHttpRequest 不能设置同步操作,设置了之后contenttype就不能设置blob,否则出错。我没时间去处理了,就用异步了。

5. 由于服务器端我命名规则还没有订好,因此我只是返回固定的一个图片,这样只要在前端能够顺利显示,说明整个路子都走通了。

6. 获取图片对象费了老大劲,原来tinymce自己是一个iframe,因此要先找到iframe,然后再找到里面的图片。 在chrome里面我直接用getElementById(”图片的id“)却始终找不到,奇怪。 后来我到Firefox中就能找到了。

7. 当服务器端把图像返回回来时,如果paste事件还没有完成,那么DOM对象还没有生成的话,图片对象是找不到的。虽然这种可能性很小,所以我设置了timeout,找不到就一直给我找,直到找到位置。当然也可以用一个wait 的gif,类似 博客园这么干。

8. 我的性子是不求甚解,能拼凑就拼凑,能猜就猜。。。。反正捣鼓出来就行了,什么代码优化之类的与我无缘。 只是我用了好多关键字搜索,但是搜出来的解决方案都有问题,所以我才写了这篇文章,希望也能帮助看文章的你节省宝贵的时间。

捣鼓TinyMCE粘贴图片并上传+Flask后台的更多相关文章

  1. 捣鼓TinyMCE 粘贴图片并上传+Django后台

    前面一篇写了上传到Flask后台,但是我不熟悉Flask,原先想学习一下,据说是轻量级. 但是我发现,学习会浪费我大量的时间,因为我并不是以这个为生的,我的目标只是要完成功能,让我自己能尽早使用起来, ...

  2. ckeditor 实现ctrl+v粘贴图片并上传、word粘贴带图片

    公司做的项目需要用到文本上传功能. Chrome+IE默认支持粘贴剪切板中的图片,但是我要粘贴的文章存在word里面,图片多达数十张,我总不能一张一张复制吧? 我希望打开文档doc直接复制粘贴到富文本 ...

  3. 如何在Chrome粘贴图片直接上传

    背景 截图或页面复制图片,可以直接通过Ctrl+v 粘贴上传图片 原理 操作:复制(截图)=>粘贴=>上传 监听粘贴事件=>获取剪贴板里的内容=>发请求上传 浏览器:Chrom ...

  4. div中粘贴图片并上传服务器 div中拖拽图片文件并上传服务器

    应用简介:此文主要是描述如何在前端div中直接ctrl+v 粘贴图片,并上传到服务器,包括拖拽图片文件到div中 应用场景描述:用QQ或者其它切图软件截图,在指定的div中ctrl+v 粘贴并显示,点 ...

  5. h5可预览 图片ajax上传 ,后台有点弱不知道数据怎么取,但是可以肯定数据上传成功了

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. xhEditor实现ctrl+v粘贴word图片并上传

    自动导入Word图片,或者粘贴Word内容时自动上传所有的图片,并且最终保留Word样式,这应该是Web编辑器里面最基本的一个需求功能了.一般情况下我们将Word内容粘贴到Web编辑器(富文本编辑器) ...

  7. umeditor实现ctrl+v粘贴word图片并上传

    图片的复制无非有两种方法,一种是图片直接上传到服务器,另外一种转换成二进制流的base64码目前限chrome浏览器使用首先以um-editor的二进制流保存为例:打开umeditor.js,找到UM ...

  8. ueditor实现ctrl+v粘贴word图片并上传

    图片的复制无非有两种方法,一种是图片直接上传到服务器,另外一种转换成二进制流的base64码 目前限chrome浏览器使用,但是项目要求需要支持所有的浏览器,包括Windows和macOS系统.没有办 ...

  9. kindeditor实现ctrl+v粘贴word图片并上传

    Chrome+IE默认支持粘贴剪切板中的图片,但是我要发布的文章存在word里面,图片多达数十张,我总不能一张一张复制吧?Chrome高版本提供了可以将单张图片转换在BASE64字符串的功能.但是无法 ...

随机推荐

  1. 仿iphone动态萤火虫锁屏应用安卓源码

    该源码是仿iphone动态萤火虫锁屏应用源码,源码SkyLock,这也是最近弄了一款锁屏,苦于市场百般阻拦与锁屏应用数量实在太多,于是将它拿出来开源:废话不多说,希望大家能够希望,更多说明请看下面的吧 ...

  2. (转)Arcgis for javascript实现百度地图ABCD marker的效果

    概述: 在我的博客中,有一篇相关的文章,这段时间,有很多人问我求源码,只是时间过去已长,源代码已找不到,乘着这个9.3放假,又重新实现了下,并相关代码做了优化,在此贴出来,方便大家使用. 相关文章地址 ...

  3. 大白_uva10795_新汉诺塔

    题意:给出所有盘子的初态和终态,问最少多少步能从初态走到终态,其余规则和老汉诺塔一样. 思路: 若要把当前最大的盘子m从1移动到3,那么首先必须把剩下的所有盘子1~m-1放到2上,然后把m放到3上. ...

  4. Windows系统设置与北京Internet时间同步

    找到提供Ntp服务器的网址:http://support.ntp.org/我从中找到东北大学的: ntp.neu.edu.cn  ( 202.118.1.46 ) 长话短说,下面开始设置: 修改后的值 ...

  5. Day 13 进程和线程

    进程和线程 今天我们使用的计算机早已进入多CPU或多核时代,而我们使用的操作系统都是支持“多任务”的操作系统,这使得我们可以同时运行多个程序,也可以将一个程序分解为若干个相对独立的子任务,让多个子任务 ...

  6. 为什么Java中的密码优先使用 char[] 而不是String?

    可以看下壁虎的回答:https://www.zhihu.com/question/36734157 String是常量(即创建之后就无法更改),会保存到常量池中,如果有其他进程可以dump这个进程的内 ...

  7. [TyvjP1515] 子串统计 [luoguP2408] 不同子串个数(后缀数组)

    Tyvj传送门 luogu传送门 经典题 统计一个字符串中不同子串的个数 一个字符串中的所有子串就是所有后缀的前缀 先求出后缀数组,求出后缀数组中相邻两后缀的 lcp 那么按照后缀数组中的顺序遍历求解 ...

  8. 火星人 2004年NOIP全国联赛普及组

    题目描述 Description 人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法.这种交流方法是这样的,首先,火星人把一个 ...

  9. 刷新PHP缓冲区

    为你的站点加速_php技巧 在当前 PHP 版本的默认配置下,“输出缓冲(Output Buffering)”是被打开的.旧版本则不是这样,在旧版本的 PHP 中,字符串在每次被输出的时候(通过 ec ...

  10. node.js 如何完美的从命令行接收参数所传递进来的值

    https://segmentfault.com/q/1010000000367285