APIs জুড়ে ব্যবহারকারীর সক্রিয়করণ সামঞ্জস্যপূর্ণ করা

Mustaq Ahmed
জো মেডলি
Joe Medley

পপআপ, পূর্ণস্ক্রীন ইত্যাদির মতো সংবেদনশীল API-এর অপব্যবহার থেকে ক্ষতিকারক স্ক্রিপ্টগুলিকে প্রতিরোধ করতে, ব্রাউজারগুলি ব্যবহারকারী সক্রিয়করণের মাধ্যমে সেই APIগুলিতে অ্যাক্সেস নিয়ন্ত্রণ করে। ব্যবহারকারীর অ্যাক্টিভেশন হল ব্যবহারকারীর ক্রিয়াকলাপের ক্ষেত্রে একটি ব্রাউজিং সেশনের অবস্থা: একটি "সক্রিয়" অবস্থা সাধারণত বোঝায় যে ব্যবহারকারী বর্তমানে পৃষ্ঠাটির সাথে ইন্টারঅ্যাক্ট করছেন বা পৃষ্ঠা লোড হওয়ার পর থেকে একটি ইন্টারঅ্যাকশন সম্পন্ন করেছেন৷ ব্যবহারকারীর অঙ্গভঙ্গি একই ধারণার জন্য একটি জনপ্রিয় কিন্তু বিভ্রান্তিকর শব্দ। উদাহরণস্বরূপ, একজন ব্যবহারকারীর দ্বারা একটি সোয়াইপ বা ফ্লিক অঙ্গভঙ্গি একটি পৃষ্ঠা সক্রিয় করে না এবং তাই স্ক্রিপ্টের দৃষ্টিকোণ থেকে, একটি ব্যবহারকারী সক্রিয়করণ নয়।

প্রধান ব্রাউজারগুলি আজকে ব্যবহারকারীর অ্যাক্টিভেশন কীভাবে অ্যাক্টিভেশন-গেটেড APIগুলিকে নিয়ন্ত্রণ করে তার চারপাশে ব্যাপকভাবে ভিন্ন আচরণ দেখায়। ক্রোমে, বাস্তবায়নটি একটি টোকেন-ভিত্তিক মডেলের উপর ভিত্তি করে করা হয়েছিল যা সমস্ত অ্যাক্টিভেশন-গেটেড এপিআইগুলির মধ্যে একটি সামঞ্জস্যপূর্ণ আচরণকে সংজ্ঞায়িত করতে খুব জটিল বলে প্রমাণিত হয়েছিল। উদাহরণস্বরূপ, Chrome postMessage() এবং setTimeout() কলের মাধ্যমে অ্যাক্টিভেশন-গেটেড API-এ অসম্পূর্ণ অ্যাক্সেসের অনুমতি দিচ্ছে; এবং ব্যবহারকারীর সক্রিয়করণ প্রতিশ্রুতি , XHR , গেমপ্যাড ইন্টারঅ্যাকশন ইত্যাদির সাথে সমর্থিত ছিল না৷ মনে রাখবেন যে এর মধ্যে কিছু জনপ্রিয় এখনও দীর্ঘস্থায়ী বাগ৷

সংস্করণ 72-এ, Chrome ব্যবহারকারী অ্যাক্টিভেশন v2 পাঠায় যা সমস্ত অ্যাক্টিভেশন-গেটেড API-এর জন্য ব্যবহারকারীর অ্যাক্টিভেশন উপলব্ধতা সম্পূর্ণ করে। এটি উপরে উল্লিখিত অসঙ্গতিগুলি সমাধান করে (এবং আরও কয়েকটি, যেমন MessageChannels ), যা আমরা বিশ্বাস করি যে ব্যবহারকারী সক্রিয়করণের চারপাশে ওয়েব বিকাশ সহজ হবে৷ অধিকন্তু, নতুন বাস্তবায়ন একটি প্রস্তাবিত নতুন স্পেসিফিকেশনের জন্য একটি রেফারেন্স বাস্তবায়ন প্রদান করে যার লক্ষ্য দীর্ঘমেয়াদে সমস্ত ব্রাউজারকে একত্রিত করা।

কিভাবে ব্যবহারকারী সক্রিয়করণ v2 কাজ করে?

নতুন API ফ্রেম অনুক্রমের প্রতিটি window অবজেক্টে একটি দুই-বিট ব্যবহারকারী অ্যাক্টিভেশন অবস্থা বজায় রাখে: ঐতিহাসিক ব্যবহারকারী অ্যাক্টিভেশন অবস্থার জন্য একটি স্টিকি বিট (যদি কোনো ফ্রেম কখনও ব্যবহারকারীর সক্রিয়করণ দেখে থাকে), এবং বর্তমান অবস্থার জন্য একটি ক্ষণস্থায়ী বিট (যদি একটি ফ্রেম প্রায় এক সেকেন্ডের মধ্যে একটি ব্যবহারকারী সক্রিয়করণ দেখেছে)। স্টিকি বিট সেট হওয়ার পরে ফ্রেমের জীবদ্দশায় কখনই রিসেট হয় না। ক্ষণস্থায়ী বিট প্রতিটি ব্যবহারকারীর ইন্টারঅ্যাকশনে সেট করা হয়, এবং একটি মেয়াদ শেষ হওয়ার পর (প্রায় এক সেকেন্ড) অথবা একটি অ্যাক্টিভেশন-গ্রাহক API (যেমন window.open() ) কলের মাধ্যমে পুনরায় সেট করা হয়।

উল্লেখ্য যে বিভিন্ন অ্যাক্টিভেশন-গেটেড এপিআই বিভিন্ন উপায়ে ব্যবহারকারী অ্যাক্টিভেশনের উপর নির্ভর করে; নতুন API এই API-নির্দিষ্ট আচরণের কোনো পরিবর্তন করছে না। যেমন ব্যবহারকারীর অ্যাক্টিভেশনের জন্য শুধুমাত্র একটি পপআপ অনুমোদিত কারণ window.open() ব্যবহারকারীর অ্যাক্টিভেশন ব্যবহার করে যেমন এটি ছিল, Navigator.prototype.vibrate() কার্যকর হতে থাকে যদি কোনো ফ্রেম (বা এর কোনো সাবফ্রেম) কখনো ব্যবহারকারীর অ্যাকশন দেখে থাকে , এবং তাই.

কি পরিবর্তন হচ্ছে?

  • ইউজার অ্যাক্টিভেশন v2 ফ্রেমের সীমানা জুড়ে ব্যবহারকারীর সক্রিয়করণ দৃশ্যমানতার ধারণাকে আনুষ্ঠানিক করে: একটি নির্দিষ্ট ফ্রেমের সাথে ব্যবহারকারীর মিথস্ক্রিয়া এখন তাদের উত্স নির্বিশেষে সমস্ত ফ্রেম (এবং শুধুমাত্র সেই ফ্রেমগুলি) সক্রিয় করবে। (Chrome 72-এ, সমস্ত একই-অরিজিন ফ্রেমে দৃশ্যমানতা প্রসারিত করার জন্য আমাদের কাছে একটি অস্থায়ী সমাধান রয়েছে। ব্যবহারকারীর অ্যাক্টিভেশনকে স্পষ্টভাবে সাব-ফ্রেমে পাস করার উপায় পেলে আমরা এই সমাধানটি সরিয়ে দেব।)
  • যখন একটি অ্যাক্টিভেশন-গেটেড এপিআই একটি অ্যাক্টিভেটেড ফ্রেম থেকে কিন্তু একটি ইভেন্ট হ্যান্ডলার কোডের বাইরে থেকে কল করা হয়, এটি ততক্ষণ কাজ করবে যতক্ষণ না ব্যবহারকারীর অ্যাক্টিভেশন স্টেট "সক্রিয়" থাকে (যেমন মেয়াদ শেষ বা সেবন করা হয়নি)। ব্যবহারকারী সক্রিয়করণ v2 এর আগে, এটি নিঃশর্তভাবে ব্যর্থ হবে।
  • মেয়াদোত্তীর্ণ সময়ের ব্যবধানের মধ্যে একাধিক অব্যবহৃত ব্যবহারকারীর মিথস্ক্রিয়া শেষ মিথস্ক্রিয়াটির সাথে সম্পর্কিত একটি একক অ্যাক্টিভেশনে ফিউজ হয়ে যায়।

অ্যাক্টিভেশন-গেটেড API-এ ধারাবাহিকতার উদাহরণ

এখানে পপআপ উইন্ডোর ( window.open() ব্যবহার করে খোলা) দুটি উদাহরণ রয়েছে যা দেখায় কিভাবে ব্যবহারকারী অ্যাক্টিভেশন v2 অ্যাক্টিভেশন-গেটেড API-এর আচরণকে সামঞ্জস্যপূর্ণ করে তোলে।

চেইন করা setTimeout() কল

এই উদাহরণটি আমাদের setTimeout() ডেমো থেকে। যদি একটি click হ্যান্ডলার এক সেকেন্ডের মধ্যে একটি পপআপ খোলার চেষ্টা করে, তবে কোডটি বিলম্ব যেভাবেই "কম্পোজ" করুক না কেন এটি সফল হবে বলে আশা করা যায়। ইউজার অ্যাক্টিভেশন v2 এই প্রত্যাশা পূরণ করে, তাই নিচের প্রতিটি ইভেন্ট হ্যান্ডলার একটি click একটি পপআপ খোলে (100ms বিলম্বের সাথে):

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

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

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

ব্যবহারকারী অ্যাক্টিভেশন v2 ছাড়া, দ্বিতীয় ইভেন্ট হ্যান্ডলার আমাদের পরীক্ষা করা সমস্ত ব্রাউজারে ব্যর্থ হয়। (এমনকি প্রথমটি কিছু ক্ষেত্রে ব্যর্থ হয়।)

ক্রস-ডোমেন postMessage() কল

এখানে আমাদের postMessage() ডেমো থেকে একটি উদাহরণ। ধরুন একটি ক্রস-অরিজিন সাবফ্রেমে একটি click হ্যান্ডলার সরাসরি প্যারেন্ট ফ্রেমে দুটি বার্তা পাঠায়। প্যারেন্ট ফ্রেম এই বার্তাগুলির মধ্যে একটি পাওয়ার পরে একটি পপআপ খুলতে সক্ষম হওয়া উচিত (কিন্তু উভয়ই নয়):

// 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);
});

ইউজার অ্যাক্টিভেশন v2 ছাড়া, দ্বিতীয় বার্তাটি পাওয়ার পরে প্যারেন্ট ফ্রেম একটি পপআপ খুলতে পারে না। এমনকি প্রথম বার্তাটি ব্যর্থ হয় যদি এটি অন্য ক্রস-অরিজিন ফ্রেমে "শৃঙ্খল" হয় (অন্য কথায়, যদি প্রথম রিসিভার অন্যের কাছে বার্তাটি ফরোয়ার্ড করে)।

এটি ইউজার অ্যাক্টিভেশন v2 এর সাথে কাজ করে, মূল আকারে এবং চেইনিংয়ের সাথে।