[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"content-xheditor_paste_images":3,"$fwt223m7vqo3v":23},{"id":4,"type":5,"slug":6,"title":7,"date":8,"category":9,"tags":10,"body_markdown":14,"permalink":15,"excerpt_src":16,"media_type":16,"media_title":16,"media_author":16,"media_url":16,"rating":16,"layout":16,"pv":17,"admin_only":17,"created_at":18,"updated_at":18,"deleted_at":16,"status":19,"html":20,"excerpt":21,"cover":22},157,"article","xheditor_paste_images","xheditor从剪贴板粘贴图片的实现原理","2011-11-30 10:08","web",[11,12,13],"剪贴板","复制","粘贴","\r\n[xheditor](http:\u002F\u002Fxheditor.com\u002F)是一个优秀的国产富文本编辑器，最近的（其实我也不知道有多久了）版本推出了一个粘贴剪贴板图片的功能，很是喜爱，好奇了好久，最终不住去看了下源码，基本明白了。\r\n\r\n> 2016-07-29 似乎这个编辑器也很久没更新了，现在对上面这段话持保留态度，不做推荐。\r\n\r\n首先，这个功能很新，不支持IE系列浏览器……用的是一些新的API。我手上的代码是1.1.10，所以代码行数以这个版本为准。\r\n\r\n一点前置小知识是必备的，那就是对大部分截图软件来说，截图操作是一个把截取的图片转换成指定格式（windows自带的是bmp）然后放入剪贴板的过程。所以，要粘贴图片，核心就是读取剪贴板。\r\n\r\n\u003C!-- more -->\r\n\r\n## 一、读取剪贴板的时机\r\n\r\n近几年浏览器在拼标准、拼性能的时候，其实也在暗里拼安全，为了防止某个网页一打开就自动把你剪贴板的内容传网上去（IE6可以做到），现代浏览器不允许随时读写剪贴板。\r\n\r\n浏览器为我们提供了`onpaste`事件（粘贴），读取剪贴板数据仅能在该事件发生时在事件处理程序中进行。因这里理解就好，所以就不贴代码。\r\n\r\n## 二、图片数据\r\n\r\n之所以IE不能粘贴图片，就在于IE没有处理二进制文件的机制，它只能处理文本。\r\n\r\n在现代浏览器中，则有关于文件的API，这里用到的就是File Reader，主要用来处理二进制文件数据。\r\n\r\n首先，在xheditor的第1922行，有一个`cleanPaste()`函数，它的作用就是读取剪贴板的数据，然后放入编辑器中，具体见代码注释。\r\n\r\n```javascript\r\nvar clipboardData,items,item;\u002F\u002Ffor chrome\r\n\r\n\u002F\u002Fev是事件，其实大家都喜欢用e或者evt或者event\r\n\u002F\u002F这句主要是确定剪贴板中是否有图片\r\nif(ev&&\r\n\t(clipboardData=ev.originalEvent.clipboardData)&&\r\n\t(items=clipboardData.items)&&\r\n\t(item=items[0])&&item.kind=='file'&&item.type.match(\u002F^image\\\u002F\u002Fi)\r\n){\r\n\tvar blob = item.getAsFile(),\t\u002F\u002Fblob就是剪贴板中的二进制图片数据\r\n\t\treader = new FileReader();\r\n\r\n\t\u002F\u002F定义fileReader读取完数据后的回调\r\n\treader.onload=function(){\r\n\t\tvar sHtml='\u003Cimg src=\"'+event.target.result+'\">';\t\u002F\u002Fresult是base64编码后的图片\r\n\t\t\u002F\u002F这里执行了一个将base64上报到服务器，然后将图片url从base64编码的图片数据换成上传后的图片地址\r\n\t\tsHtml=replaceRemoteImg(sHtml);\r\n\t\t_this.pasteHTML(sHtml);\u002F\u002F这里应该是关于光标和插入代码的具体操作\r\n\t}\r\n\r\n\treader.readAsDataURL(blob);\t\u002F\u002F用fileReader读取二进制图片，完成后会调用上面定义的回调函数\r\n\treturn false;\r\n}\r\n```\r\n\r\n好吧，本来还想写下中间上报到服务器的代码的，想了想觉得也没什么很特别的地方。最多是把base64数据当成普通URL上报，然后服务端再解码成图片。\r\n\r\n嗯。就这样，当笔记了。\r\n","\u002Farticle\u002Fxheditor_paste_images.html",null,0,"2026-08-28 04:37:17","published","\u003Cp>\u003Ca href=\"http:\u002F\u002Fxheditor.com\u002F\">xheditor\u003C\u002Fa>是一个优秀的国产富文本编辑器，最近的（其实我也不知道有多久了）版本推出了一个粘贴剪贴板图片的功能，很是喜爱，好奇了好久，最终不住去看了下源码，基本明白了。\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>2016-07-29 似乎这个编辑器也很久没更新了，现在对上面这段话持保留态度，不做推荐。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>首先，这个功能很新，不支持IE系列浏览器……用的是一些新的API。我手上的代码是1.1.10，所以代码行数以这个版本为准。\u003C\u002Fp>\n\u003Cp>一点前置小知识是必备的，那就是对大部分截图软件来说，截图操作是一个把截取的图片转换成指定格式（windows自带的是bmp）然后放入剪贴板的过程。所以，要粘贴图片，核心就是读取剪贴板。\u003C\u002Fp>\n\u003Ch2>一、读取剪贴板的时机\u003C\u002Fh2>\n\u003Cp>近几年浏览器在拼标准、拼性能的时候，其实也在暗里拼安全，为了防止某个网页一打开就自动把你剪贴板的内容传网上去（IE6可以做到），现代浏览器不允许随时读写剪贴板。\u003C\u002Fp>\n\u003Cp>浏览器为我们提供了\u003Ccode>onpaste\u003C\u002Fcode>事件（粘贴），读取剪贴板数据仅能在该事件发生时在事件处理程序中进行。因这里理解就好，所以就不贴代码。\u003C\u002Fp>\n\u003Ch2>二、图片数据\u003C\u002Fh2>\n\u003Cp>之所以IE不能粘贴图片，就在于IE没有处理二进制文件的机制，它只能处理文本。\u003C\u002Fp>\n\u003Cp>在现代浏览器中，则有关于文件的API，这里用到的就是File Reader，主要用来处理二进制文件数据。\u003C\u002Fp>\n\u003Cp>首先，在xheditor的第1922行，有一个\u003Ccode>cleanPaste()\u003C\u002Fcode>函数，它的作用就是读取剪贴板的数据，然后放入编辑器中，具体见代码注释。\u003C\u002Fp>\n\u003Cpre>\u003Ccode>var clipboardData,items,item;\u002F\u002Ffor chrome\n\n\u002F\u002Fev是事件，其实大家都喜欢用e或者evt或者event\n\u002F\u002F这句主要是确定剪贴板中是否有图片\nif(ev&amp;&amp;\n\t(clipboardData=ev.originalEvent.clipboardData)&amp;&amp;\n\t(items=clipboardData.items)&amp;&amp;\n\t(item=items[0])&amp;&amp;item.kind=='file'&amp;&amp;item.type.match(\u002F^image\\\u002F\u002Fi)\n){\n\tvar blob = item.getAsFile(),\t\u002F\u002Fblob就是剪贴板中的二进制图片数据\n\t\treader = new FileReader();\n\n\t\u002F\u002F定义fileReader读取完数据后的回调\n\treader.onload=function(){\n\t\tvar sHtml='&lt;img src=&quot;'+event.target.result+'&quot;&gt;';\t\u002F\u002Fresult是base64编码后的图片\n\t\t\u002F\u002F这里执行了一个将base64上报到服务器，然后将图片url从base64编码的图片数据换成上传后的图片地址\n\t\tsHtml=replaceRemoteImg(sHtml);\n\t\t_this.pasteHTML(sHtml);\u002F\u002F这里应该是关于光标和插入代码的具体操作\n\t}\n\n\treader.readAsDataURL(blob);\t\u002F\u002F用fileReader读取二进制图片，完成后会调用上面定义的回调函数\n\treturn false;\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>好吧，本来还想写下中间上报到服务器的代码的，想了想觉得也没什么很特别的地方。最多是把base64数据当成普通URL上报，然后服务端再解码成图片。\u003C\u002Fp>\n\u003Cp>嗯。就这样，当笔记了。\u003C\u002Fp>\n","\u003Cp>\u003Ca href=\"http:\u002F\u002Fxheditor.com\u002F\">xheditor\u003C\u002Fa>是一个优秀的国产富文本编辑器，最近的（其实我也不知道有多久了）版本推出了一个粘贴剪贴板图片的功能，很是喜爱，好奇了好久，最终不住去看了下源码，基本明白了。\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>2016-07-29 似乎这个编辑器也很久没更新了，现在对上面这段话持保留态度，不做推荐。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>首先，这个功能很新，不支持IE系列浏览器……用的是一些新的API。我手上的代码是1.1.10，所以代码行数以这个版本为准。\u003C\u002Fp>\n\u003Cp>一点前置小知识是必备的，那就是对大部分截图软件来说，截图操作是一个把截取的图片转换成指定格式（windows自带的是bmp）然后放入剪贴板的过程。所以，要粘贴图片，核心就是读取剪贴板。\u003C\u002Fp>\n","",{"total":17,"totalRoots":17,"comments":24,"pv":17},[]]