• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com专业计算机教程网站
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure
您的位置:首页 > 网页设计 >html5 > 关于知乎回答问题编辑框用Ctrl+V 粘贴图片是如何实现的详解

关于知乎回答问题编辑框用Ctrl+V 粘贴图片是如何实现的详解

作者:匿名 字体:[增加 减小] 来源:互联网 时间:2018-12-03

本文主要包含HTML5,编辑框,粘贴图片等相关知识,匿名希望在学习及工作中可以帮助到您
貌似我没有像QQ邮箱之类的装知乎的插件
是用HTML5的新功能实现的吗?
看了@朱利安 的回答,发现我描述的不够清楚
我是用QQ截图之类的工具截的图,然后图片本身是保存在剪切板里的,剪切板中保存的*不是*图片的地址
大家可以自己试一下,用QQ截张图,然后在下面的编辑框里 Ctrl+V 一下

回复内容:

呵呵,刚发现知乎编辑器有这么强的功能,赶紧研究一下,记录如下

  1. 抓包
    截个图,然后粘贴到编辑器,查看 HTTP 包,发现有对upload.zhihu.com/upload 的请求
    request 的格式是multipart/form-data; 图片的内容作为request body 的一部分一起传了过去
    这里大概就能推测出基本原理了:监听粘贴 → 获取粘贴内容 → 将内容上传

  2. 搜索代码
    在 rich_text_editor.js 里面搜索 /upload 字样,搜到了这么一段

this.Vz = "http://upload." + Ak.Sl + ":" + location.port + "/upload";

估计是设置属性,那么再搜 .Vz 看看哪里用到了,于是看到

function zE(a, b) {
    var c = new FormData;
    c.append("via", "xhr2");
    c.append("upload_file", b);
    var d;
    d = $.ajaxSettings.xhr();
    d.withCredentials = i;
    var f = $.ajax({url: a.Vz,data: c,processData: l,contentType: l,xhr: function() {
            return d
        },type: "POST"}).done(function(a) {

啊,找到了,这里应该就是发送图片数据的地方,而且用了 FormData 这个 HTML5 特性
简单说就是 ajax 以前只能向服务器发送文本,而 HTML5 提供的 XMLHttpRequest Level2 现在支持发送二进制数据了,这里的 c.append("upload_file", b) 里面 b 应该就是那个图片的二进制数据

打断点
继续追踪就容易多了,只要在这个地方打个断点,然后往编辑器里面粘贴一个截图
Chrome 调试工具的 Call Stack 就会告诉你,程序的上一步在哪里

1320.jpg

看一看 a 对象的属性基本可以断定它是一个 Event 对象,而且这里的这段 function 就是对粘贴事件的处理,为了验证,搜索一下 .rw 就会看到这样一段

a.f().addEventListener("paste", u(this.rw, this));

确定推断无误,可以看到上面的处理函数中,通过 a.clipboardData 就能取到剪贴板中的数据,并且可以通过 clipboardData.types 来判断数据是不是图片。
这么高级的 API 是哪里来的呢?搜一下就知道了 Clipboard API and events
可以看到这个 API 属于 W3C 的标准(当然还是草案阶段),但是不属于 HTML5
另外代码中的重点是这么一段

c.type.indexOf("image") && (zE(b, c.getAsFile()), a.preventDefault())

zE 就是上面的那个 ajax 发送函数,而通过 c.getAsFile() 可以从剪贴板中获取二进制的数据

结论
通过 Clipboard API 可以在用户粘贴时获知粘贴的内容,包括内容的格式(是否为图片),内容的二进制数据等等
通过 XMLHttpRequest Level2 可以实现将二进制数据以 ajax 的方式发送到服务器,即实现了上传功能
当然以上都需要浏览器的支持,估计IE下就悲剧了
最后,我现在迫切期待新浪微博的发布框能支持这个功能

这个和 HTML5 没有太大关系,网页浏览器很早就有这个标准了,不同浏览器下的实现接口略有区别。
粘贴(包括富文本、图片等各种格式的内容)是利用了 contentEditable p 的 onPaste 事件。

知乎的 JavaScript 源代码经过了混淆和压缩,非人类可阅读的,所以我就不扒他的代码了。
当在编辑器上执行粘贴的时候,onPaste 事件被触发,同时有一个事件参数 event,包含 clipboardData 的属性。
简单来说,代码逻辑可能是这样的:

function onPasteEvent (e) {
   if (e && e.clipboardData && e.clipboardData.getData) 
   {
        if (/image/.test(e.clipboardData.types)) 
        {
            //粘贴图片
            var imageContent = e.clipboardData.getData('image/xxxx');
            //检测图片来源
            //如果是最原始的 data,比如 QQ 截图、Word 里复制所产生,直接把 data 上传
            //这一部分可能用了是 HTML5 中 HTTP_CONTENT_DISPOSITION 上传机制
            //除了 HTML5,非显式的 input[type="file"] 应该是无法上传文件的
            //如果是 file,上传到知乎服务器
            //如果是外部网站 URL,后台 curl get 转移到知乎服务器
            //最后生成一个知乎的 URL,作为 img 标签插入到 contentEditable div 中
        }
        else if (/text\/plain/.test(e.clipboardData.types)) {
            //粘贴简单文本 ....
        }
        else 
        {
            //....
        }

        if (e.preventDefault) 
        {
            e.stopPropagation();
            e.preventDefault();
        }
        return false;
    }}

以上就是关于知乎回答问题编辑框用Ctrl+V 粘贴图片是如何实现的详解的内容,更多相关内容请关注微课江湖()!

您可能想查找下面的文章:

  • HTML5知识点总结
  • HTML5的本地存储
  • HTML5本地存储之IndexedDB
  • Html5实现文件异步上传功能
  • Html5新标签datalist实现输入框与后台数据库数据的动态匹配
  • 详解HTML5 window.postMessage与跨域
  • HTML5拖放API实现拖放排序的实例代码
  • 解决html5中video标签无法播放mp4问题的办法
  • HTML5新特性 多线程(Worker SharedWorker)
  • Html5新增标签有哪些

相关文章

  • 2018-12-03详解强大的HTML5幻灯片系统-H5Slides
  • 2018-12-03一款利用html5和css3动画排列人物头像的实例演示_html5教程技巧
  • 2018-12-03<acronym> 和 <abbr> 这两个标签有什么本质上的区别吗?
  • 2017-08-06使用html5 canvas创建太空游戏的示例
  • 2018-12-03html5规定元素是否可拖动的属性draggable
  • 2018-12-03SVG(可缩放矢量图形)图片添加、高斯模糊、渐变与g标签
  • 2018-12-03HTML5 Plus 实现手机APP拍照或相册选择图片上传的功能
  • 2018-12-03HTML5实战与剖析之CSS选择器——querySelector()
  • 2018-12-03详细介绍WebSocket API HTML5规范翻译
  • 2018-12-03HTML5实践-使用CSS实现弹性视频的代码分享

文章分类

  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure

最近更新的内容

    • html特殊符号示例 html特殊字符编码对照表_html5教程技巧
    • NodeJS与HTML5相结合实现拖拽多个文件上传到服务器的实现方法
    • html5的button标签何时使用?为什么主流网站在非跳转按钮上仍然使用a标签?
    • 10款HTML5编码简化工具
    • 「W3C HTML5 中文兴趣小组」是个什么样的小组?
    • HTML5 Canvas图像处理技巧
    • 详细介绍25+免费的Bootstrap HTML5网站模板图文详情
    • 《css权威指南》与《html5与css3权威指南》那个更权威更先进?
    • 淘宝的HTML5页面,为什么要把默认滚动给禁了?
    • 弹性盒模型 flex box的认知与使用

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有