Kullanıcı etkinleştirmesini API'ler arasında tutarlı hale getirme

Mustaq Ahmed
Joe Medley
Joe Medley

Kötü amaçlı komut dosyalarının pop-up'lar gibi hassas API'leri kötüye kullanmasını önlemek için tam ekran vb. olması durumunda tarayıcılar, bu API'lere kullanıcı etkinleştirme. Kullanıcı etkinleştirme, ilgili göz atma oturumunun kullanıcı işlemlerine: "etkin" durumu genellikle kullanıcının şu anda sayfayla etkileşimde bulunuyor veya sayfadan bu yana bir etkileşim gerçekleştirmiş yükleyin. Kullanıcı hareketi, aynı fikir için popüler olsa da yanıltıcı bir terimdir. Örneğin, Örneğin, bir kullanıcının kaydırma veya vurma hareketinin bir sayfayı etkinleştirmemesi komut dosyası açısından kullanıcı etkinleştirmesi değildir.

Günümüzde başlıca tarayıcılar, kullanıcı etkinleştirme yönteminin nasıl çok farklı davranışlar sergilediğini göstermektedir. etkinleştirmeyle korunan API'leri kontrol eder. Chrome'da uygulama, tutarlı bir rapor oluşturamayacak kadar karmaşık olduğu ortaya çıktı. bu davranışına sahip. Örneğin Chrome, etkinleştirme korumalı API'lere eksik erişime izin verme postMessage() ve setTimeout() arama; ve kullanıcı etkinleştirmesinin Promises ile desteklenir. XHR, Oyun kumandası etkileşimi vb. popüler ancak uzun süredir var olan hatalardır.

Sürüm 72'de Chrome, kullanıcının etkinleştirme denetimi tüm API'ler için etkinleştirme kullanılabilirliği tamamlandı. Şu sorunu çözer: yukarıda bahsedilen tutarsızlıklar (ve bir kaç tane daha MessageChannels) içeren ve web'i kolaylaştıracağını düşünüyoruz. ilgili geliştirdiğimiz yeni özellikler hakkında konuşacağız. Ayrıca yeni uygulama, önerilen bir uygulama için resmî onay yeni spesifikasyon bir araya getirmeyi amaçlayan bir girişimdir.

Kullanıcı Etkinleştirme v2 nasıl çalışır?

Yeni API, her window nesnesinde iki bitlik kullanıcı etkinleştirme durumunu korur değeri için sabit bir bit kullanabilirsiniz (zaman çizelgesine ilişkin bir kullanıcı etkinleştirmesi gördüğünde) ve geçerli durum için geçici bir bit (bir kare yaklaşık bir saniye içinde kullanıcı etkinleştirmesini gördüyse). Yapışkan bit ayarlandıktan sonra karenin ömrü boyunca hiçbir zaman sıfırlanmaz. Geçici bit Her kullanıcı etkileşiminde ayarlanır ve kullanım süresi dolduktan sonra sıfırlanır. bir zaman aralığı (yaklaşık bir saniye) veya etkinleştirme tüketen bir API'ye çağrı (ör. window.open()).

Farklı etkinleştirme erişimli API'lerin çeşitli şekillerde, yeni API, API'ye özgü bu davranışlardan hiçbirini değiştirmemektedir. Ör. window.open() şunu tükettiğinden, kullanıcı etkinleştirmesi başına yalnızca bir pop-up'a izin verilir eskiden olduğu gibi, Navigator.prototype.vibrate() kullanıcı aktivasyonunu bir çerçeve (veya alt çerçevelerinden herhangi biri) kullanıcının bir işlem yaptığını veya vb.

Neler değişiyor?

  • Kullanıcı Etkinleştirme v2, kullanıcı etkinleştirme görünürlüğü kavramını resmileştiriyor anlamına gelir. Artık kullanıcının belirli bir çerçeveyle etkileşimi içeren tüm çerçeveleri (ve yalnızca bu çerçeveleri) kaynak. (Chrome 72'de, görünürlük ayarını açık duruma getirin. Şu sorunu giderdikten sonra bu geçici çözümü hem de karşınızdaki kişinin kullanıcı etkinleştirmesini açık bir şekilde alt çerçevelere iletmenize olanak tanır.)
  • Etkinleştirme korumalı API, etkinleştirilmiş bir çerçeveden ancak yoksa, kullanıcı etkinleştirme işlemi etkin olduğu sürece durum "etkin" (ör. süresi dolmamış veya tüketilmemiş olmalıdır). Kullanıcıdan Önce Etkinleştirme v2, koşulsuz olarak başarısız olur.
  • Sona erme zaman aralığı sigortalarında birden fazla kullanılmayan kullanıcı etkileşimi son etkileşime karşılık gelen tek bir etkinleştirmeye dönüştürür.

Etkinleştirme korumalı API'lerde tutarlılık örnekleri

Aşağıda, window.open() kullanılarak açılmış olan) pop-up pencereli Kullanıcı Etkinleştirme v2'nin, etkinleştirme kontrollü API'lerin davranışını nasıl yaptığını göster tutarlı olması gerekir.

Zincirlenen setTimeout() arama

Bu örnek, setTimeout() demomuza katılabilirsiniz. click işleyicisi bir saniye içinde pop-up açmaya çalışırsa kod nasıl "oluşturulduğundan" bağımsız olarak başarılı Geciktirme. Kullanıcı Etkinleştirme v2 sürümü karşılanıyor gösterir. Bu nedenle, aşağıdaki etkinlik işleyicilerin her biri click (100 ms gecikmeyle):

function popupAfter100ms() {
  setTimeout(callWindowOpen, 100);
}

function asyncPopupAfter100ms() {
  setTimeout(popupAfter100ms, 0);
}

someButton.addEventListener('click', popupAfter100ms);
someButton.addEventListener('click', asyncPopupAfter100ms);

Kullanıcı Etkinleştirme v2 olmadığında, ikinci etkinlik işleyici, test edilir. (İlki bile başarısız olabilir bazı durumlarda kullanılabilir.)

Alanlar arası postMessage() çağrıları

Kendi proje yöneticiliği postMessage() demomuza katılabilirsiniz. Kaynaklar arası alt çerçevedeki bir click işleyicinin doğrudan iki mesaj gönderdiğini varsayalım bunu üst çerçeveye ekler. Üst çerçevenin ardından pop-up açılabilmesi gerekir. şu iletilerden birini alıyorsanız (ikisini birden değil):

// Parent frame code
window.addEventListener('message', e => {
  if (e.data === 'open_popup' && e.origin === child_origin)
    window.open('about:blank');
});

// Child frame code:
someButton.addEventListener('click', () => {
  parent.postMessage('hi_there', parent_origin);
  parent.postMessage('open_popup', parent_origin);
});

Kullanıcı Etkinleştirme v2 olmadan, üst çerçeve alındıktan sonra pop-up açılamaz oluşturuyoruz. "Zincirli" olan ilk ileti bile başarısız oluyor başka bir kullanıcıya çapraz kaynak çerçeve (başka bir deyişle, ilk alıcı iletiyi yönlendirirse) .

Bu, Kullanıcı Etkinleştirme v2 ile hem orijinal biçimde hem de zincirlemedir.