ज़्यादा सुरक्षित, टेक्स्ट और इमेज के लिए क्लिपबोर्ड का ऐक्सेस अनब्लॉक किया गया
सिस्टम क्लिपबोर्ड तक पहुंचने का पारंपरिक तरीका
document.execCommand()
क्लिपबोर्ड इंटरैक्शन के लिए. हालांकि, कटिंग का यह तरीका काफ़ी इस्तेमाल होता है, लेकिन
चिपकाने के लिए शुल्क लग गया: क्लिपबोर्ड का ऐक्सेस सिंक्रोनस था, और
और DOM पर लिखें.
टेक्स्ट के छोटे-छोटे हिस्सों के लिए यह ठीक है, लेकिन कई मामलों में
क्लिपबोर्ड ट्रांसफ़र के लिए इस्तेमाल किया जाने वाला पेज खराब है. सैनिटाइज़ेशन में समय लगता है या
कॉन्टेंट को सुरक्षित तरीके से चिपकाने से पहले, इमेज को डिकोड करने की ज़रूरत पड़ सकती है. ब्राउज़र
चिपकाए गए दस्तावेज़ से लिंक किए गए संसाधनों को लोड या इनलाइन करने की ज़रूरत पड़ सकती है. यह होगा
डिस्क या नेटवर्क पर इंतज़ार करते समय पेज को ब्लॉक करें. अनुमतियां जोड़ने के बारे में सोचें
शामिल करते समय यह ज़रूरी है कि ब्राउज़र अनुरोध करते समय पेज को ब्लॉक कर दे
क्लिपबोर्ड का ऐक्सेस. साथ ही, वे अनुमतियां जो अपने-आप लागू होती हैं
क्लिपबोर्ड इंटरैक्शन के लिए document.execCommand()
में बदलाव किए जाते हैं और ये अलग-अलग होते हैं
ब्राउज़र के बीच सेट कर सकते हैं.
कॉन्टेंट बनाने एसिंक्रोनस क्लिपबोर्ड एपीआई इन समस्याओं को हल करता है. साथ ही, अनुमतियों का एक बेहतर मॉडल उपलब्ध कराता है, जो पेज ब्लॉक करें. Async Clipboard API, सिर्फ़ टेक्स्ट और इमेज मैनेज करने के लिए काम करता है ज़्यादातर ब्राउज़र पर इस्तेमाल किए जा सकते हैं, लेकिन उनके लिए अलग-अलग तरह से काम करने में मदद मिलती है. ब्राउज़र को अच्छी तरह से पढ़ना न भूलें साथ ही, नीचे दिए गए सभी सेक्शन के साथ काम करने से जुड़ी खास जानकारी देखें.
कॉपी करें: क्लिपबोर्ड पर डेटा लिखना
writeText()
टेक्स्ट को क्लिपबोर्ड पर कॉपी करने के लिए, writeText()
पर कॉल करें. क्योंकि यह एपीआई
तो writeText()
फ़ंक्शन ऐसा प्रॉमिस लौटाता है जो समाधान करता है या
इस आधार पर अस्वीकार करता है कि पास किया गया टेक्स्ट कॉपी हुआ है या नहीं:
async function copyPageUrl() {
try {
await navigator.clipboard.writeText(location.href);
console.log('Page URL copied to clipboard');
} catch (err) {
console.error('Failed to copy: ', err);
}
}
write()
दरअसल, सामान्य write()
के लिए writeText()
सिर्फ़ एक आसान तरीका है
तरीका है, जिसकी मदद से आप इमेज को क्लिपबोर्ड पर कॉपी कर सकते हैं. writeText()
की तरह, यह
एसिंक्रोनस है और प्रॉमिस नतीजे देता है.
क्लिपबोर्ड पर एक चित्र लिखने के लिए, आपको चित्र के रूप में
blob
. ऐसा करने का एक तरीका
इसे ऐसा करने के लिए, fetch()
का इस्तेमाल करके सर्वर से इमेज का अनुरोध करें. इसके बाद, इस नंबर पर कॉल करें
blob()
जवाब.
किसी
में हो सकता है. अच्छी बात यह है कि आप इमेज को कैनवस पर भी बना सकते हैं और
कैनवस को कॉल करें'
toBlob()
तरीका.
इसके बाद, write()
में पैरामीटर के तौर पर ClipboardItem
ऑब्जेक्ट के कलेक्शन को पास करें
तरीका. फ़िलहाल, एक बार में सिर्फ़ एक इमेज शेयर की जा सकती है. हालांकि, हमें उम्मीद है कि
आने वाले समय में कई इमेज के लिए सुविधा उपलब्ध होगी. ClipboardItem
एक ऑब्जेक्ट लेता है
कुंजी के रूप में इमेज के एमआईएमई टाइप और वैल्यू के तौर पर ब्लॉब. BLOB के लिए
fetch()
या canvas.toBlob()
, blob.type
प्रॉपर्टी से मिले ऑब्जेक्ट
इसमें इमेज के लिए सही MIME टाइप अपने-आप शामिल हो जाता है.
try {
const imgURL = '/images/generic/file.png';
const data = await fetch(imgURL);
const blob = await data.blob();
await navigator.clipboard.write([
new ClipboardItem({
// The key is determined dynamically based on the blob's type.
[blob.type]: blob
})
]);
console.log('Image copied.');
} catch (err) {
console.error(err.name, err.message);
}
इसके अलावा, ClipboardItem
ऑब्जेक्ट के लिए प्रॉमिस भी लिखा जा सकता है.
इस पैटर्न के लिए, आपको पहले से डेटा के एमआईएमई टाइप की जानकारी होनी चाहिए.
try {
const imgURL = '/images/generic/file.png';
await navigator.clipboard.write([
new ClipboardItem({
// Set the key beforehand and write a promise as the value.
'image/png': fetch(imgURL).then(response => response.blob()),
})
]);
console.log('Image copied.');
} catch (err) {
console.error(err.name, err.message);
}
कॉपी इवेंट
ऐसे मामले में जब कोई उपयोगकर्ता क्लिपबोर्ड कॉपी शुरू करता है
और preventDefault()
को कॉल नहीं करता
copy
इवेंट
में clipboardData
प्रॉपर्टी शामिल है, जिसके आइटम पहले से ही सही फ़ॉर्मैट में हैं.
अगर आपको अपना लॉजिक लागू करना है, तो preventDefault()
को कॉल करना होगा
डिफ़ॉल्ट व्यवहार को आपके खुद के लागू करने के पक्ष में होने से रोकता है.
इस मामले में, clipboardData
खाली रहेगा.
ऐसे पेज पर ध्यान दें जिसमें टेक्स्ट और इमेज हो. साथ ही, जब उपयोगकर्ता पूरा और
क्लिपबोर्ड कॉपी शुरू करता है, तो आपके कस्टम समाधान को सिर्फ़ टेक्स्ट खारिज करना चाहिए और
इमेज को कॉपी करें. कोड सैंपल में दिए गए तरीके की मदद से, यह काम किया जा सकता है.
इस उदाहरण में यह नहीं बताया गया है कि जल्दी कैसे जाएं
एपीआई, जब क्लिपबोर्ड एपीआई काम नहीं करता हो.
<!-- The image we want on the clipboard. -->
<img src="kitten.webp" alt="Cute kitten.">
<!-- Some text we're not interested in. -->
<p>Lorem ipsum</p>
document.addEventListener("copy", async (e) => {
// Prevent the default behavior.
e.preventDefault();
try {
// Prepare an array for the clipboard items.
let clipboardItems = [];
// Assume `blob` is the blob representation of `kitten.webp`.
clipboardItems.push(
new ClipboardItem({
[blob.type]: blob,
})
);
await navigator.clipboard.write(clipboardItems);
console.log("Image copied, text ignored.");
} catch (err) {
console.error(err.name, err.message);
}
});
copy
इवेंट के लिए:
ClipboardItem
के लिए:
चिपकाएं: क्लिपबोर्ड से डेटा पढ़ा जा रहा है
readText()
क्लिपबोर्ड पर मौजूद टेक्स्ट पढ़ने के लिए, navigator.clipboard.readText()
पर कॉल करें और इंतज़ार करें
वापस किए गए प्रॉमिस के समाधान के लिए:
async function getClipboardContents() {
try {
const text = await navigator.clipboard.readText();
console.log('Pasted content: ', text);
} catch (err) {
console.error('Failed to read clipboard contents: ', err);
}
}
read()
navigator.clipboard.read()
तरीका एसिंक्रोनस भी होता है और
वादा करना. क्लिपबोर्ड से कोई इमेज पढ़ने के लिए,
ClipboardItem
ऑब्जेक्ट को दोहराया जा सकता है.
हर ClipboardItem
में अलग-अलग तरह का कॉन्टेंट हो सकता है. इसलिए, आपको:
यह प्रक्रिया for...of
लूप का इस्तेमाल करके, टाइप की सूची में दोहराई जाती है. हर तरह के लिए,
पाने के लिए, getType()
तरीके को तर्क के रूप में कॉल करें
संबंधित BLOB. पहले की तरह, यह कोड इमेज से नहीं जुड़ा है और
काम करने के लिए अन्य फ़ाइल टाइप का इस्तेमाल करें.
async function getClipboardContents() {
try {
const clipboardItems = await navigator.clipboard.read();
for (const clipboardItem of clipboardItems) {
for (const type of clipboardItem.types) {
const blob = await clipboardItem.getType(type);
console.log(URL.createObjectURL(blob));
}
}
} catch (err) {
console.error(err.name, err.message);
}
}
चिपकाई गई फ़ाइलों के साथ काम करना
यह उपयोगकर्ताओं के लिए क्लिपबोर्ड कीबोर्ड शॉर्टकट, जैसे कि ctrl+c और ctrl+v. Chromium, रीड-ओनली फ़ाइलों को क्लिपबोर्ड पर दिखाता है, जैसा कि नीचे बताया गया है. यह तब ट्रिगर होता है, जब उपयोगकर्ता किसी ऑपरेटिंग सिस्टम में, चिपकाने के लिए डिफ़ॉल्ट शॉर्टकट को हिट करता है या जब उपयोगकर्ता बदलाव करें पर क्लिक करता है और फिर ब्राउज़र के मेन्यू बार में चिपकाएं पर क्लिक करता है. किसी और प्लंबिंग कोड की ज़रूरत नहीं है.
document.addEventListener("paste", async e => {
e.preventDefault();
if (!e.clipboardData.files.length) {
return;
}
const file = e.clipboardData.files[0];
// Read the file's contents, assuming it's a text file.
// There is no way to write back to it.
console.log(await file.text());
});
चिपकाने के इवेंट
जैसा कि पहले बताया गया है, क्लिपबोर्ड एपीआई के साथ काम करने के लिए, कई इवेंट शुरू करने की योजना है.
लेकिन अभी के लिए आप मौजूदा paste
इवेंट का इस्तेमाल कर सकते हैं. यह नए के साथ ठीक से काम करता है
क्लिपबोर्ड टेक्स्ट पढ़ने के लिए एसिंक्रोनस तरीके. copy
इवेंट की तरह ही, ये काम न करें
preventDefault()
को कॉल करना भूल जाओ.
document.addEventListener('paste', async (e) => {
e.preventDefault();
const text = await navigator.clipboard.readText();
console.log('Pasted text: ', text);
});
एक से ज़्यादा MIME टाइप हैंडल करना
लागू करने की ज़्यादातर प्रोसेस में, क्लिपबोर्ड पर एक कट के लिए कई डेटा फ़ॉर्मैट होते हैं कार्रवाई को कॉपी करने का विकल्प होता है. इसकी दो वजहें हैं: ऐप्लिकेशन डेवलपर के तौर पर, आपके पास उन ऐप्लिकेशन की क्षमताओं के बारे में नहीं पता जिनमें उपयोगकर्ता टेक्स्ट या इमेज कॉपी करना चाहता है, कई ऐप्लिकेशन, स्ट्रक्चर्ड डेटा को सामान्य टेक्स्ट के तौर पर चिपकाने की सुविधा देते हैं. आम तौर पर, यह उपयोगकर्ताओं को बदलाव करें मेन्यू आइटम के साथ पेश किया गया था, जैसे कि चिपकाएं और मिलान शैली या फ़ॉर्मैट किए बिना चिपकाएं.
नीचे दिए गए उदाहरण में इसका तरीका बताया गया है. इस उदाहरण में, वैल्यू को पाने के लिए fetch()
का इस्तेमाल किया गया है
नहीं है, लेकिन यह
<canvas>
या फ़ाइल सिस्टम ऐक्सेस एपीआई.
async function copy() {
const image = await fetch('kitten.png').then(response => response.blob());
const text = new Blob(['Cute sleeping kitten'], {type: 'text/plain'});
const item = new ClipboardItem({
'text/plain': text,
'image/png': image
});
await navigator.clipboard.write([item]);
}
सुरक्षा और अनुमतियां
क्लिपबोर्ड ऐक्सेस होने की वजह से, ब्राउज़र को सुरक्षा से जुड़ी चिंता का सामना करना पड़ता है. इसके बिना
इस्तेमाल करने की अनुमति दी है, तो पेज नुकसान पहुंचाने वाले कॉन्टेंट को चुपचाप कॉपी कर सकता है
के क्लिपबोर्ड पर कॉपी किया जाता है, जिससे चिपकाने पर खराब नतीजे मिलेंगे.
कल्पना कीजिए कि आप एक ऐसे वेब पेज पर जाएँ जो rm -rf /
या
डिकंप्रेशन बम की इमेज
आपके क्लिपबोर्ड पर.
![ब्राउज़र का प्रॉम्प्ट, जिसमें उपयोगकर्ता से क्लिपबोर्ड इस्तेमाल करने की अनुमति मांगी जा रही है.](https://web.dev/static/articles/async-clipboard/image/browser-prompt-asking-us-40b4cf43bf01.png?authuser=7&hl=hi)
वेब पेजों को क्लिपबोर्ड पर पढ़ने का ऐक्सेस देना और भी आसान है परेशानी भरा. उपयोगकर्ता, पासवर्ड और अन्य संवेदनशील जानकारी जैसे कि पासवर्ड और निजी जानकारी को क्लिपबोर्ड पर सेव किया जाएगा, जिसे किसी भी पेज पर पढ़ा जा सकेगा उपयोगकर्ता की जानकारी होती है.
कई नए एपीआई की तरह ही, Clipboard API सिर्फ़ उन पेजों के लिए काम करता है जो एचटीटीपीएस. गलत इस्तेमाल को रोकने के लिए, क्लिपबोर्ड का ऐक्सेस सिर्फ़ तब दिया जाता है, जब पेज सक्रिय टैब पर क्लिक करें. इस्तेमाल किए जा रहे टैब में मौजूद पेज, क्लिपबोर्ड पर डेटा कॉपी किए बिना लिख सकते हैं अनुमति चाहता है, लेकिन क्लिपबोर्ड से पढ़ने के लिए हमेशा अनुमति.
कॉपी करने और चिपकाने की अनुमतियां
अनुमतियां एपीआई.
पेजों को clipboard-write
की अनुमति अपने-आप मिल जाती है. ऐसा तब होता है, जब वे
सक्रिय टैब पर क्लिक करें. clipboard-read
की अनुमति का अनुरोध करना ज़रूरी है. हालांकि, आपके पास
वाला काम आसान है. नीचे दिया गया कोड बाद वाला कोड दिखाता है:
const queryOpts = { name: 'clipboard-read', allowWithoutGesture: false };
const permissionStatus = await navigator.permissions.query(queryOpts);
// Will be 'granted', 'denied' or 'prompt':
console.log(permissionStatus.state);
// Listen for changes to the permission state
permissionStatus.onchange = () => {
console.log(permissionStatus.state);
};
यह भी कंट्रोल किया जा सकता है कि कट लगाने के लिए, उपयोगकर्ता के जेस्चर की ज़रूरत है या नहीं या
allowWithoutGesture
विकल्प का इस्तेमाल करके चिपकाएं. इस वैल्यू का डिफ़ॉल्ट
ब्राउज़र के अनुसार अलग-अलग होता है, इसलिए आपको इसे हमेशा शामिल करना चाहिए.
यहां बताया गया है कि क्लिपबोर्ड एपीआई की एसिंक्रोनस सुविधा कितने काम आती है: क्लिपबोर्ड डेटा को पढ़ने या लिखने की कोशिश करने पर, उपयोगकर्ता को की अनुमति नहीं दी गई है. यह एपीआई प्रॉमिस पर आधारित होता है, यह पूरी तरह से पारदर्शी है. साथ ही, इन वजहों से क्लिपबोर्ड को ऐक्सेस करने की अनुमति नहीं देने वाले किसी उपयोगकर्ता ने पेज को अस्वीकार करने का वादा करता है, ताकि पेज सही तरीके से जवाब दे सके.
किसी पेज के ऐक्टिव टैब होने पर ही ब्राउज़र, क्लिपबोर्ड को ऐक्सेस करने की अनुमति देते हैं.
तो आपको पता चलेगा कि यहां दिखाए गए कुछ उदाहरण
ब्राउज़र का कंसोल, क्योंकि डेवलपर टूल खुद ही सक्रिय टैब हैं. इसमें एक तरकीब है: टाल दें
setTimeout()
का इस्तेमाल करके क्लिपबोर्ड को ऐक्सेस करें. इसके बाद, पेज में फटाफट क्लिक करके
फ़ंक्शन को कॉल किए जाने से पहले इस पर फ़ोकस करें:
setTimeout(async () => {
const text = await navigator.clipboard.readText();
console.log(text);
}, 2000);
अनुमतियों की नीति का इंटिग्रेशन
iframe में एपीआई इस्तेमाल करने के लिए, आपको इसके साथ इसे चालू करना होगा
अनुमतियों की नीति,
जो ऐसा तरीका तय करती है जो चुनिंदा तरीके से चालू करने और
ब्राउज़र की कई सुविधाओं और एपीआई को बंद कर देता है. सीधे तौर पर, आपको इनमें से कोई एक
या clipboard-read
या clipboard-write
, दोनों का इस्तेमाल करें.
<iframe
src="index.html"
allow="clipboard-read; clipboard-write"
>
</iframe>
सुविधा की पहचान
सभी ब्राउज़र पर काम करते हुए एसिंक्रोनस क्लिपबोर्ड एपीआई का इस्तेमाल करने के लिए,
navigator.clipboard
और पुराने तरीकों पर वापस जाएं. उदाहरण के लिए, यहां इसका तरीका देखें
तो आप अन्य ब्राउज़र को शामिल करने के लिए चिपकाने की सुविधा लागू कर सकते है.
document.addEventListener('paste', async (e) => {
e.preventDefault();
let text;
if (navigator.clipboard) {
text = await navigator.clipboard.readText();
}
else {
text = e.clipboardData.getData('text/plain');
}
console.log('Got pasted text: ', text);
});
यह पूरी कहानी नहीं है. Async Clipboard API के पहले, अलग-अलग फ़ॉर्मैट में
वेब ब्राउज़र में कॉपी और पेस्ट करने की अलग-अलग सुविधाएं शामिल हैं. ज़्यादातर ब्राउज़र में,
ब्राउज़र की अपनी कॉपी और पेस्ट को
document.execCommand('copy')
और document.execCommand('paste')
. अगर टेक्स्ट
कॉपी करने के लिए एक स्ट्रिंग है, जो DOM में मौजूद नहीं है, उसे
DOM और चयनित:
button.addEventListener('click', (e) => {
const input = document.createElement('input');
input.style.display = 'none';
document.body.appendChild(input);
input.value = text;
input.focus();
input.select();
const result = document.execCommand('copy');
if (result === 'unsuccessful') {
console.error('Failed to copy text.');
}
input.remove();
});
डेमो
नीचे दिए गए डेमो में, एसिंक्रोनस क्लिपबोर्ड एपीआई इस्तेमाल किया जा सकता है. ग्लिच यू टेक्स्ट डेमो को रीमिक्स कर सकते हैं या इमेज डेमो को उनके साथ एक्सपेरिमेंट करें.
पहले उदाहरण में, टेक्स्ट को क्लिपबोर्ड पर चालू और बंद करने के बारे में बताया गया है.
इमेज के साथ एपीआई को आज़माने के लिए, इस डेमो का इस्तेमाल करें. याद रखें कि सिर्फ़ PNG फ़ॉर्मैट में फ़ाइल अपलोड की जा सकती है और सिर्फ़ कुछ ब्राउज़र पर.
इसी विषय से जुड़े कुछ लिंक
स्वीकार की गई
एसिंक्रोनस क्लिपबोर्ड एपीआई डारविन ने लागू किया था हुआंग और गैरी कैकमर्किक. डार्विन ने भी डेमो दिया. इसके लिए, क्यारिक और फिर गैरी कैकमर्क को धन्यवाद इस लेख के कुछ हिस्सों की समीक्षा करें.
मार्कस विंकलर की हीरो इमेज चालू है अनस्प्लैश.