php编译工具 知乎,关于知乎回答问题编辑框用Ctrl+V 粘贴图片是如何实现的详解...
貌似我沒(méi)有像QQ郵箱之類的裝知乎的插件
是用HTML5的新功能實(shí)現(xiàn)的嗎?
看了@朱利安 的回答,發(fā)現(xiàn)我描述的不夠清楚
我是用QQ截圖之類的工具截的圖,然后圖片本身是保存在剪切板里的,剪切板中保存的*不是*圖片的地址
大家可以自己試一下,用QQ截張圖,然后在下面的編輯框里 Ctrl+V 一下
回復(fù)內(nèi)容:
呵呵,剛發(fā)現(xiàn)知乎編輯器有這么強(qiáng)的功能,趕緊研究一下,記錄如下抓包
截個(gè)圖,然后粘貼到編輯器,查看 HTTP 包,發(fā)現(xiàn)有對(duì)upload.zhihu.com/upload 的請(qǐng)求
request 的格式是multipart/form-data; 圖片的內(nèi)容作為request body 的一部分一起傳了過(guò)去
這里大概就能推測(cè)出基本原理了:監(jiān)聽(tīng)粘貼 → 獲取粘貼內(nèi)容 → 將內(nèi)容上傳
搜索代碼
在 rich_text_editor.js 里面搜索 /upload 字樣,搜到了這么一段this.Vz = "http://upload." + Ak.Sl + ":" + location.port + "/upload";
估計(jì)是設(shè)置屬性,那么再搜 .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) {
啊,找到了,這里應(yīng)該就是發(fā)送圖片數(shù)據(jù)的地方,而且用了 FormData 這個(gè) HTML5 特性
簡(jiǎn)單說(shuō)就是 ajax 以前只能向服務(wù)器發(fā)送文本,而 HTML5 提供的 XMLHttpRequest Level2 現(xiàn)在支持發(fā)送二進(jìn)制數(shù)據(jù)了,這里的 c.append("upload_file", b) 里面 b 應(yīng)該就是那個(gè)圖片的二進(jìn)制數(shù)據(jù)
打斷點(diǎn)
繼續(xù)追蹤就容易多了,只要在這個(gè)地方打個(gè)斷點(diǎn),然后往編輯器里面粘貼一個(gè)截圖
Chrome 調(diào)試工具的 Call Stack 就會(huì)告訴你,程序的上一步在哪里
看一看 a 對(duì)象的屬性基本可以斷定它是一個(gè) Event 對(duì)象,而且這里的這段 function 就是對(duì)粘貼事件的處理,為了驗(yàn)證,搜索一下 .rw 就會(huì)看到這樣一段a.f().addEventListener("paste", u(this.rw, this));
確定推斷無(wú)誤,可以看到上面的處理函數(shù)中,通過(guò) a.clipboardData 就能取到剪貼板中的數(shù)據(jù),并且可以通過(guò) clipboardData.types 來(lái)判斷數(shù)據(jù)是不是圖片。
這么高級(jí)的 API 是哪里來(lái)的呢?搜一下就知道了 Clipboard API and events
可以看到這個(gè) API 屬于 W3C 的標(biāo)準(zhǔn)(當(dāng)然還是草案階段),但是不屬于 HTML5
另外代碼中的重點(diǎn)是這么一段c.type.indexOf("image") && (zE(b, c.getAsFile()), a.preventDefault())
zE 就是上面的那個(gè) ajax 發(fā)送函數(shù),而通過(guò) c.getAsFile() 可以從剪貼板中獲取二進(jìn)制的數(shù)據(jù)
結(jié)論
通過(guò) Clipboard API 可以在用戶粘貼時(shí)獲知粘貼的內(nèi)容,包括內(nèi)容的格式(是否為圖片),內(nèi)容的二進(jìn)制數(shù)據(jù)等等
通過(guò) XMLHttpRequest Level2 可以實(shí)現(xiàn)將二進(jìn)制數(shù)據(jù)以 ajax 的方式發(fā)送到服務(wù)器,即實(shí)現(xiàn)了上傳功能
當(dāng)然以上都需要瀏覽器的支持,估計(jì)IE下就悲劇了
最后,我現(xiàn)在迫切期待新浪微博的發(fā)布框能支持這個(gè)功能
這個(gè)和 HTML5 沒(méi)有太大關(guān)系,網(wǎng)頁(yè)瀏覽器很早就有這個(gè)標(biāo)準(zhǔn)了,不同瀏覽器下的實(shí)現(xiàn)接口略有區(qū)別。
粘貼(包括富文本、圖片等各種格式的內(nèi)容)是利用了 contentEditable p 的 onPaste 事件。
知乎的 JavaScript 源代碼經(jīng)過(guò)了混淆和壓縮,非人類可閱讀的,所以我就不扒他的代碼了。
當(dāng)在編輯器上執(zhí)行粘貼的時(shí)候,onPaste 事件被觸發(fā),同時(shí)有一個(gè)事件參數(shù) event,包含 clipboardData 的屬性。
簡(jiǎn)單來(lái)說(shuō),代碼邏輯可能是這樣的:function onPasteEvent (e) {
if (e && e.clipboardData && e.clipboardData.getData)
{
if (/image/.test(e.clipboardData.types))
{
//粘貼圖片
var imageContent = e.clipboardData.getData('image/xxxx');
//檢測(cè)圖片來(lái)源
//如果是最原始的 data,比如 QQ 截圖、Word 里復(fù)制所產(chǎn)生,直接把 data 上傳
//這一部分可能用了是 HTML5 中 HTTP_CONTENT_DISPOSITION 上傳機(jī)制
//除了 HTML5,非顯式的 input[type="file"] 應(yīng)該是無(wú)法上傳文件的
//如果是 file,上傳到知乎服務(wù)器
//如果是外部網(wǎng)站 URL,后臺(tái) curl get 轉(zhuǎn)移到知乎服務(wù)器
//最后生成一個(gè)知乎的 URL,作為 img 標(biāo)簽插入到 contentEditable div 中
}
else if (/text\/plain/.test(e.clipboardData.types)) {
//粘貼簡(jiǎn)單文本 ....
}
else
{
//....
}
if (e.preventDefault)
{
e.stopPropagation();
e.preventDefault();
}
return false;
}}
以上就是關(guān)于知乎回答問(wèn)題編輯框用Ctrl+V 粘貼圖片是如何實(shí)現(xiàn)的詳解的內(nèi)容,更多相關(guān)內(nèi)容請(qǐng)關(guān)注PHP中文網(wǎng)(www.php.cn)!
本文原創(chuàng)發(fā)布php中文網(wǎng),轉(zhuǎn)載請(qǐng)注明出處,感謝您的尊重!
總結(jié)
以上是生活随笔為你收集整理的php编译工具 知乎,关于知乎回答问题编辑框用Ctrl+V 粘贴图片是如何实现的详解...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: c++驱动键鼠源码,C++ 驱动打印机源
- 下一篇: matlab三参数拟合函数,数据拟合,有