实现右键直接粘贴在文本框上,图片上传到服务器并返回一个img的地址,适配IE11、FF、Chrome。这个是前台,用wangEditor测试,用户需引入wangEditor.min.js。 wangEditor demo 欢迎使用 wangEditor 富
引入的 paste.js ,在GitHub上看到的一个适配主流浏览器的粘贴图片的轮子。wangEditor demo 欢迎使用 wangEditor 富文本编辑器
// 源地址 https://github.com/layerssss/paste.js/ (function() { var $, Paste, createHiddenEditable, dataURLtoBlob, isFocusable; $ = window.jQuery; $.paste = function(pasteContainer) { var pm; if (typeof console !== "undefined" && console !== null) { console.log("DEPRECATED: This method is deprecated. Please use $.fn.pastableNonInputable() instead."); } pm = Paste.mountNonInputable(pasteContainer); return pm._container; }; $.fn.pastableNonInputable = function() { var el, j, len, ref; ref = this; for (j = 0, len = ref.length; j < len; j++) { el = ref[j]; if (el._pastable || $(el).is('textarea, input:text, [contenteditable]')) { continue; } Paste.mountNonInputable(el); el._pastable = true; } return this; }; $.fn.pastableTextarea = function() { var el, j, len, ref; ref = this; for (j = 0, len = ref.length; j < len; j++) { el = ref[j]; if (el._pastable || $(el).is(':not(textarea, input:text)')) { continue; } Paste.mountTextarea(el); el._pastable = true; } return this; }; $.fn.pastableContenteditable = function() { var el, j, len, ref; ref = this; for (j = 0, len = ref.length; j < len; j++) { el = ref[j]; if (el._pastable || $(el).is(':not([contenteditable])')) { continue; } Paste.mountContenteditable(el); el._pastable = true; } return this; }; dataURLtoBlob = function(dataURL, sliceSize) { var b64Data, byteArray, byteArrays, byteCharacters, byteNumbers, contentType, i, m, offset, ref, slice; if (sliceSize == null) { sliceSize = 512; } if (!(m = dataURL.match(/^data\:([^\;]+)\;base64\,(.+)$/))) { return null; } ref = m, m = ref[0], contentType = ref[1], b64Data = ref[2]; byteCharacters = atob(b64Data); byteArrays = []; offset = 0; while (offset < byteCharacters.length) { slice = byteCharacters.slice(offset, offset + sliceSize); byteNumbers = new Array(slice.length); i = 0; while (i < slice.length) { byteNumbers[i] = slice.charCodeAt(i); i++; } byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); offset += sliceSize; } return new Blob(byteArrays, { type: contentType }); }; createHiddenEditable = function() { return $(document.createElement('div')).attr('contenteditable', true).attr('aria-hidden', true).attr('tabindex', -1).css({ width: 1, height: 1, position: 'fixed', left: -100, overflow: 'hidden' }); }; isFocusable = function(element, hasTabindex) { var fieldset, focusableIfVisible, img, map, mapName, nodeName; map = void 0; mapName = void 0; img = void 0; focusableIfVisible = void 0; fieldset = void 0; nodeName = element.nodeName.toLowerCase(); if ('area' === nodeName) { map = element.parentNode; mapName = map.name; if (!element.href || !mapName || map.nodeName.toLowerCase() !== 'map') { return false; } img = $('img[usemap=\'#' + mapName + '\']'); return img.length > 0 && img.is(':visible'); } if (/^(input|select|textarea|button|object)$/.test(nodeName)) { focusableIfVisible = !element.disabled; if (focusableIfVisible) { fieldset = $(element).closest('fieldset')[0]; if (fieldset) { focusableIfVisible = !fieldset.disabled; } } } else if ('a' === nodeName) { focusableIfVisible = element.href || hasTabindex; } else { focusableIfVisible = hasTabindex; } focusableIfVisible = focusableIfVisible || $(element).is('[contenteditable]'); return focusableIfVisible && $(element).is(':visible'); }; Paste = (function() { Paste.prototype._target = null; Paste.prototype._container = null; Paste.mountNonInputable = function(nonInputable) { var paste; paste = new Paste(createHiddenEditable().appendTo(nonInputable), nonInputable); $(nonInputable).on('click', (function(_this) { return function(ev) { if (!isFocusable(ev.target, false)) { return paste._container.focus(); } }; })(this)); paste._container.on('focus', (function(_this) { return function() { return $(nonInputable).addClass('pastable-focus'); }; })(this)); return paste._container.on('blur', (function(_this) { return function() { return $(nonInputable).removeClass('pastable-focus'); }; })(this)); }; Paste.mountTextarea = function(textarea) { var ctlDown, paste, ref, ref1; if ((typeof DataTransfer !== "undefined" && DataTransfer !== null ? DataTransfer.prototype : void 0) && ((ref = Object.getOwnPropertyDescriptor) != null ? (ref1 = ref.call(Object, DataTransfer.prototype, 'items')) != null ? ref1.get : void 0 : void 0)) { return this.mountContenteditable(textarea); } paste = new Paste(createHiddenEditable().insertBefore(textarea), textarea); ctlDown = false; $(textarea).on('keyup', function(ev) { var ref2; if ((ref2 = ev.keyCode) === 17 || ref2 === 224) { ctlDown = false; } return null; }); $(textarea).on('keydown', function(ev) { var ref2; if ((ref2 = ev.keyCode) === 17 || ref2 === 224) { ctlDown = true; } if ((ev.ctrlKey != null) && (ev.metaKey != null)) { ctlDown = ev.ctrlKey || ev.metaKey; } if (ctlDown && ev.keyCode === 86) { paste._textarea_focus_stolen = true; paste._container.focus(); paste._paste_event_fired = false; setTimeout((function(_this) { return function() { if (!paste._paste_event_fired) { $(textarea).focus(); return paste._textarea_focus_stolen = false; } }; })(this), 1); } return null; }); $(textarea).on('paste', (function(_this) { return function() {}; })(this)); $(textarea).on('focus', (function(_this) { return function() { if (!paste._textarea_focus_stolen) { return $(textarea).addClass('pastable-focus'); } }; })(this)); $(textarea).on('blur', (function(_this) { return function() { if (!paste._textarea_focus_stolen) { return $(textarea).removeClass('pastable-focus'); } }; })(this)); $(paste._target).on('_pasteCheckContainerDone', (function(_this) { return function() { $(textarea).focus(); return paste._textarea_focus_stolen = false; }; })(this)); return $(paste._target).on('pasteText', (function(_this) { return function(ev, data) { var content, curEnd, curStart; curStart = $(textarea).prop('selectionStart'); curEnd = $(textarea).prop('selectionEnd'); content = $(textarea).val(); $(textarea).val("" + content.slice(0, curStart) + data.text + content.slice(curEnd)); $(textarea)[0].setSelectionRange(curStart + data.text.length, curStart + data.text.length); return $(textarea).trigger('change'); }; })(this)); }; Paste.mountContenteditable = function(contenteditable) { var paste; paste = new Paste(contenteditable, contenteditable); $(contenteditable).on('focus', (function(_this) { return function() { return $(contenteditable).addClass('pastable-focus'); }; })(this)); return $(contenteditable).on('blur', (function(_this) { return function() { return $(contenteditable).removeClass('pastable-focus'); }; })(this)); }; function Paste(_container, _target) { this._container = _container; this._target = _target; this._container = $(this._container); this._target = $(this._target).addClass('pastable'); this._container.on('paste', (function(_this) { return function(ev) { var clipboardData, file, item, j, k, len, len1, reader, ref, ref1, ref2, ref3, text; if (ev.currentTarget !== ev.target) { return ev.preventDefault(); } _this._paste_event_fired = true; if (((ref = ev.originalEvent) != null ? ref.clipboardData : void 0) != null) { clipboardData = ev.originalEvent.clipboardData; if (clipboardData.items) { ref1 = clipboardData.items; for (j = 0, len = ref1.length; j < len; j++) { item = ref1[j]; if (item.type.match(/^image\//)) { reader = new FileReader(); reader.onload = function(event) { return _this._handleImage(event.target.result); }; try { reader.readAsDataURL(item.getAsFile()); } catch (error) {} ev.preventDefault(); break; } if (item.type === 'text/plain') { item.getAsString(function(string) { return _this._target.trigger('pasteText', { text: string }); }); } } } else { if (-1 !== Array.prototype.indexOf.call(clipboardData.types, 'text/plain')) { text = clipboardData.getData('Text'); setTimeout(function() { return _this._target.trigger('pasteText', { text: text }); }, 1); } _this._checkImagesInContainer(function(src) { return _this._handleImage(src); }); } } if (clipboardData = window.clipboardData) { if ((ref2 = (text = clipboardData.getData('Text'))) != null ? ref2.length : void 0) { setTimeout(function() { _this._target.trigger('pasteText', { text: text }); return _this._target.trigger('_pasteCheckContainerDone'); }, 1); } else { ref3 = clipboardData.files; for (k = 0, len1 = ref3.length; k < len1; k++) { file = ref3[k]; _this._handleImage(URL.createObjectURL(file)); } _this._checkImagesInContainer(function(src) {}); } } return null; }; })(this)); } Paste.prototype._handleImage = function(src) { var loader; if (src.match(/^webkit\-fake\-url\:\/\//)) { return this._target.trigger('pasteImageError', { message: "You are trying to paste an image in Safari, however we are unable to retieve its data." }); } loader = new Image(); loader.crossOrigin = "anonymous"; loader.onload = (function(_this) { return function() { var blob, canvas, ctx, dataURL; canvas = document.createElement('canvas'); canvas.width = loader.width; canvas.height = loader.height; ctx = canvas.getContext('2d'); ctx.drawImage(loader, 0, 0, canvas.width, canvas.height); dataURL = null; try { dataURL = canvas.toDataURL('image/png'); blob = dataURLtoBlob(dataURL); } catch (error) {} if (dataURL) { return _this._target.trigger('pasteImage', { blob: blob, dataURL: dataURL, width: loader.width, height: loader.height }); } }; })(this); loader.onerror = (function(_this) { return function() { return _this._target.trigger('pasteImageError', { message: "Failed to get image from: " + src, url: src }); }; })(this); return loader.src = src; }; Paste.prototype._checkImagesInContainer = function(cb) { var img, j, len, ref, timespan; timespan = Math.floor(1000 * Math.random()); ref = this._container.find('img'); for (j = 0, len = ref.length; j < len; j++) { img = ref[j]; img["_paste_marked_" + timespan] = true; } return setTimeout((function(_this) { return function() { var k, len1, ref1; ref1 = _this._container.find('img'); for (k = 0, len1 = ref1.length; k < len1; k++) { img = ref1[k]; if (!img["_paste_marked_" + timespan]) { cb(img.src); $(img).remove(); } } return _this._target.trigger('_pasteCheckContainerDone'); }; })(this), 1); }; return Paste; })(); }).call(this);后端服务器接收并解析的 Servlet
import sun.misc.BASE64Decoder; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.util.Random; /** * Created by LXM on 2017-07-20. */ public class Servlet extends javax.servlet.http.HttpServlet { protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { try { request.setCharacterEncoding("utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } try { String data = request.getReader().readLine(); // 处理数据 System.out.println(data); Random random = new Random(); String path = random.nextInt(10000) + "." + data.split(",")[0].split("image/")[1].split(";")[0]; boolean result = GenerateImage(data.split(",")[1], "F:\\MyJavaWebs\\Server4Upload\\out\\artifacts\\Server4Upload_war_exploded\\RichTextArea\\ImgTmp\\A" + path); renderData(response, "ImgTmp\\A" + path); } catch (Exception e) { e.printStackTrace(); } } protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { } /** * base64解码成图片保存 * * @param imgStr * @param imgFilePath * @return */ public static boolean GenerateImage(String imgStr, String imgFilePath) { if (imgStr == null) // 图像数据为空 return false; BASE64Decoder decoder = new BASE64Decoder(); try { // Base64解码 byte[] bytes = decoder.decodeBuffer(imgStr); for (int i = 0; i < bytes.length; ++i) { if (bytes[i] < 0) {// 调整异常数据 bytes[i] += 256; } } // 生成图片 OutputStream out = new FileOutputStream(imgFilePath); out.write(bytes); out.flush(); out.close(); return true; } catch (Exception e) { return false; } } /** * 返回结果 * * @param response * @param path */ private void renderData(HttpServletResponse response, String path) { PrintWriter printWriter = null; try { response.setHeader("Content-type", "text/html;charset=UTF-8"); printWriter = response.getWriter(); printWriter.print(path); } catch (IOException ex) { ex.printStackTrace(); } finally { if (null != printWriter) { printWriter.flush(); printWriter.close(); } } } }