Chrome 120'den itibaren, Eş Zamansız Pano'ya yeni bir unsanitized
seçeneği eklendi
API'ye gidin. Bu seçenek, bazı durumlarda
pano içeriğini, kopyalandığı zamanki haliyle yapıştırır.
Yani, tarayıcılar tarafından yaygın olarak kullanılan herhangi bir ara temizleme adımı olmadan
iyi bir nedendir; başvurun. Bu kılavuzu nasıl kullanacağınızı bu kılavuzdan öğrenebilirsiniz.
Proje yöneticileri Async Clipboard API'si Çoğu durumda geliştiricilerin, bilgilerin doğruluğu konusunda panodaki içeriğe sahiptir ve sayfaya yazdıklarını panodaki (kopya), web sitesindeki verileri okuduklarında görecekleriyle aynıdır panoya yapıştırın (yapıştır).
Bu kesinlikle metin için geçerlidir. Aşağıdaki kodu Geliştirici Araçları'na yapıştırmayı deneyin
sonra hemen sayfaya yeniden odaklayın. (setTimeout()
gereklidir
Böylece, sayfaya odaklanmak için yeterli zamanınız olur. Bu, Eşzamansız
Clipboard API'si.) Gördüğünüz gibi giriş, çıkışla tamamen aynıdır.
setTimeout(async () => {
const input = 'Hello';
await navigator.clipboard.writeText(input);
const output = await navigator.clipboard.readText();
console.log(input, output, input === output);
// Logs "Hello Hello true".
}, 3000);
Resimlerle bu durum biraz farklıdır. Trafiğin tıkanmasının önlenmesi için sıkıştırma bombası saldırıları, tarayıcılar PNG gibi resimleri yeniden kodlayın, ancak giriş ve çıkış resimleri görsel olarak aynı, piksel başına piksel.
setTimeout(async () => {
const dataURL =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=';
const input = await fetch(dataURL).then((response) => response.blob());
await navigator.clipboard.write([
new ClipboardItem({
[input.type]: input,
}),
]);
const [clipboardItem] = await navigator.clipboard.read();
const output = await clipboardItem.getType(input.type);
console.log(input.size, output.size, input.type === output.type);
// Logs "68 161 true".
}, 3000);
Peki, HTML metinlerine ne olur? Tahmin edebileceğiniz gibi, HTML ile
farklı olduğunu anlayabilirsiniz. Bu durumda tarayıcı, hatalı olabilecek içeriği önlemek için HTML kodunu
şeylerin olmasını engelleyebilirsiniz (örneğin, HTML'den <script>
etiketlerini çıkarabilirsiniz)
kodunu (ve <meta>
, <head>
, <style>
gibi diğerleri) kullanabilir ve CSS'yi satır içine alabilirsiniz.
Aşağıdaki örneği değerlendirip Geliştirici Araçları Konsolu'nda deneyin. Bu kurstan sonra
çıkışın girişten oldukça farklı olduğuna dikkat edin.
setTimeout(async () => {
const input = `<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Excel.Sheet" />
<meta name="Generator" content="Microsoft Excel 15" />
<style>
body {
font-family: HK Grotesk;
background-color: var(--color-bg);
}
</style>
</head>
<body>
<div>hello</div>
</body>
</html>`;
const inputBlob = new Blob([input], { type: 'text/html' });
await navigator.clipboard.write([
new ClipboardItem({
'text/html': inputBlob,
}),
]);
const [clipboardItem] = await navigator.clipboard.read();
const outputBlob = await clipboardItem.getType('text/html');
const output = await outputBlob.text();
console.log(input, output);
}, 3000);
HTML temizleme işlemi genellikle iyi bir şeydir. Kendinizi teşhir etmek istemezsiniz, gerekli düzeltmeler yapılmamış HTML'ye izin vererek güvenlik sorunlarını gidermeye çalışır. Orada geliştiricinin bu senaryolarda tam olarak ne yaptığını bilmesi ve Bu noktada giriş ve çıkış HTML’sinin bütünlüğünün kritik öneme sahip olması sağlanır. Bu durumda iki seçeneğiniz vardır:
- Hem kopyalama hem de yapıştırma sonunu kontrol ediyorsanız (örneğin, aynı şekilde uygulamanızın içinde yapıştırmak için Async Clipboard API için web özel biçimleri. Burada okumayı bırakın ve bağlantılı makaleyi kontrol edin.
- Uygulamanızda yalnızca yapıştırma ucunu kontrol edip kopyalama sonunu kontrol etmiyorsanız
Bunun nedeni kopyalama işleminin
web özel biçimleri için
unsanitized
seçeneğini kullanmanız gerekir. bu makalenin devamında bulabilirsiniz.
Temizlik işlemi, script
etiketlerini kaldırma, stilleri satır içine alma ve
emin olmak için HTML’nin iyi bir şekilde biçimlendirildiğinden emin olun. Bu liste tam kapsamlı değildir ve daha fazlası
daha sonra adım adım eklenebilir.
Düzeltilmemiş HTML'yi kopyalayıp yapıştırın
Eş zamansız Clipboard API'sini kullanarak HTML'yi panoya write()
(kopyaladığınızda)
tarayıcı, bir DOM ayrıştırıcısı ile çalıştırarak iyi biçimlendirildiğinden emin olmasını sağlar
ve sonuç olarak ortaya çıkan HTML dizesi serileştiriliyor, ancak
bu adım için daha fazla bilgi edinin. Herhangi bir işlem yapmanız gerekmiyor. read()
HTML belgesinin
başka bir uygulama tarafından panoya kopyalandığında, web uygulamanız da
tam kaliteye sahip içerik ve kendi kodunuzda temizleme işlemi gerçekleştirme gereksinimi,
read()
yöntemine bir özellik nesnesi aktarabilirsiniz
unsanitized
ve ['text/html']
değeri. Tek başına şu şekilde görünür:
navigator.clipboard.read({ unsanitized: ['text/html'] })
Aşağıdaki kod örneği
aşağıda gösterilenle hemen hemen aynı, ancak bu sefer unsanitized
seçeneğini belirleyin. Geliştirici Araçları Konsolu'nda denediğinizde, girdiğiniz girişin ve
aynı olur.
setTimeout(async () => {
const input = `<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Excel.Sheet" />
<meta name="Generator" content="Microsoft Excel 15" />
<style>
body {
font-family: HK Grotesk;
background-color: var(--color-bg);
}
</style>
</head>
<body>
<div>hello</div>
</body>
</html>`;
const inputBlob = new Blob([input], { type: 'text/html' });
await navigator.clipboard.write([
new ClipboardItem({
'text/html': inputBlob,
}),
]);
const [clipboardItem] = await navigator.clipboard.read({
unsanitized: ['text/html'],
});
const outputBlob = await clipboardItem.getType('text/html');
const output = await outputBlob.text();
console.log(input, output);
}, 3000);
Tarayıcı desteği ve özellik algılama
Özelliğin desteklenip desteklenmediğini kontrol etmenin doğrudan bir yolu yoktur. Bu nedenle,
davranışı gözlemlemeye dayalıdır. Bu nedenle, aşağıdaki örnek
değer, <style>
etiketinin hayatta kalıp kalmadığına dayanır.
destekleniyor olduğunu veya satır içinde olduğunu gösterir; bu da desteklenmediği anlamına gelir. Lütfen
çalışması için, sayfanın panoyu almış olması gerekir
izni gerekir.
const supportsUnsanitized = async () => {
const input = `<style>p{color:red}</style><p>a`;
const inputBlob = new Blob([input], { type: 'text/html' });
await navigator.clipboard.write([
new ClipboardItem({
'text/html': inputBlob,
}),
]);
const [clipboardItem] = await navigator.clipboard.read({
unsanitized: ['text/html],
});
const outputBlob = await clipboardItem.getType('text/html');
const output = await outputBlob.text();
return /<style>/.test(output);
};
Demo
unsanitized
seçeneğinin işleyiş şeklini görmek için şuraya bakın:
Glitch'te demo yapın ve
kaynak kodu.
Sonuçlar
Girişte belirtildiği gibi çoğu geliştiricinin
pano temizleme ve varsayılan temizleme seçenekleriyle çalışabilir
bir web sitesini ziyaret eder. Geliştiricilerin bu konuya önem vermesi gereken nadir durumlarda,
unsanitized
seçeneği mevcut.
Faydalı bağlantı
Teşekkür
Bu makale Anupam Snigdha ve Rıza Ahmet. API belirtilmiş ve tarafından geliştirilmiştir.