php编译工具 知乎,关于知乎回答问题编辑框用Ctrl+V 粘贴图片是如何实现的详解...
貌似我沒有像QQ郵箱之類的裝知乎的插件
是用HTML5的新功能實現的嗎?
看了@朱利安 的回答,發現我描述的不夠清楚
我是用QQ截圖之類的工具截的圖,然后圖片本身是保存在剪切板里的,剪切板中保存的*不是*圖片的地址
大家可以自己試一下,用QQ截張圖,然后在下面的編輯框里 Ctrl+V 一下
回復內容:
呵呵,剛發現知乎編輯器有這么強的功能,趕緊研究一下,記錄如下抓包
截個圖,然后粘貼到編輯器,查看 HTTP 包,發現有對upload.zhihu.com/upload 的請求
request 的格式是multipart/form-data; 圖片的內容作為request body 的一部分一起傳了過去
這里大概就能推測出基本原理了:監聽粘貼 → 獲取粘貼內容 → 將內容上傳
搜索代碼
在 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 就會告訴你,程序的上一步在哪里
看一看 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 粘貼圖片是如何實現的詳解的內容,更多相關內容請關注PHP中文網(www.php.cn)!
本文原創發布php中文網,轉載請注明出處,感謝您的尊重!
總結
以上是生活随笔為你收集整理的php编译工具 知乎,关于知乎回答问题编辑框用Ctrl+V 粘贴图片是如何实现的详解...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++驱动键鼠源码,C++ 驱动打印机源
- 下一篇: matlab三参数拟合函数,数据拟合,有