ایجاد: ۱۶:۰۳ ۱۳۹۲/۱۰/۲۶
ویرایش: ۱۰:۵۵ ۱۳۹۵/۶/۱۰

آموزش‌ها

»

برنامه های تحت وب آفلاین، چرا و چگونه؟

Web Application ها به برنامه‌های تحت وب گفته می‌شود. کارکرد آفلاین یکی از قابلیت‌های html5 است که توسط اکثر مرورگرها پشتیبانی می‌شود و با کمک آن می‌توان یک وب‌اپلیکیشن را در حالت آفلاین نیز استفاده کرد. سایت intime.ir یک نمونه وب‌اپلیکیشن ساده‌ی آفلاین است. پس از یکبار مشاهده سایت مذکور، سایت خودش را برای کارکرد آفلاین آماده می‌کند و مانند برنامه‌ای عمل می‌کند که روی دستگاه شما نصب شده است. حتی بدون داشتن اینترنت می‌توانید براوزر را باز کنید و آدرس وب‌اپلیکیشن آفلاین را (که حداقل یکبار قبلا به سایتش رفته‌اید) وارد کنید و در حالت آفلاین از آن استفاده کنید.
همچنین پس از باز کردن یک وب‌اپلیکیشن در مرورگر کروم یا فایرفاکس، می‌توان گزینه Add to home screen را نیز انتخاب کرد تا میان‌بر آن وب‌اپلیکیشن به صفحه دسکتاپ شما اضافه شود و مانند یک برنامه تحت سیستم‌عامل همیشه دم دست‌تان باشد.

یک برنامه تحت وب چرا باید بتواند آفلاین کار کند؟!

دو دلیل در پاسخ به این نکته می‌توان ذکر کرد:
  1. شاید علت اصلی درنظر گرفتن این قابلیت در html5 این باشد که اگر یک برنامه تحت وب بتواند به صورت آفلاین کار کند، در مقابل اختلالات شبکه یا در دسترس نبودن آن به کار خود ادامه دهد و پس از در دسترس بودن شبکه، تغییرات احتمالی را ثبت کند.
    این امر با گسترش گوشی‌های هوشمند و تبلت ملموس‌تر شده است چرا که همه جا اینترنت بی‌سیم در دسترس نیست و از سویی هم کاربران علاقه دارند که حتی در صورت قطعی اینترنت بتوانند از امکان یک برنامه استفاده کنند. به همین دلیل این قابلیت موجب گسترش ساخت برنامه‌های تحت وبی شده است که مانند یک app و برنامه، در حالت آفلاین نیز به سادگی اجرا می‌شوند و کاربر می‌تواند با آن کار کند.
  2. ساخت یک اپلیکیشن تحت وب، این حسن را دارد که وابسته به سیستم‌عامل نیست. یعنی لازم نیست امروز دنبال برنامه‌نویس اندروید و iOS باشید و فردا دنبال برنامه‌نویس بلک‌بری و تایزن و دو سال دیگر دنبال برنامه‌نویس برای سیستم‌عامل‌های نوظهور موبایل و سایر وسایل جدید.
    یک وب‌اپلیکیشن فقط وابسته به وجود براوزر است و در هر سیستم‌عاملی هم حداقل یک براوزر وجود دارد یا قابل نصب است.

قبل از خواندن ادامه مطلب، این نکته را به یاد داشته باشید که تهیه برنامه تحت وب آفلاین، هرچند نکات تخصصی زیادی دارد و کار با آن برای تازه‌کارها ساده نخواهد بود اما برای بسیاری از سایت‌ها می‌تواند مناسب باشد. حتی سایت‌های بزرگ با میلیون‌ها صفحه (مثل ویکی پدیا) نیز می‌توانند از حالت آفلاین استفاده کنند و بجای صفحاتی که ذخیره نشده، یک صفحه حاوی پیام خاص نمایش دهد که در ادامه به روش آن اشاره شده است (FALLBACK).
همچنین توجه کنید که در حالت آفلاین می‌توان فقط مطالب استاتیک ارائه کرد اما در صورت دریافت مطلب جدیدی از کاربر در حالت آفلاین (مانند ثبت یک نظر یا ایجاد/تغییر/حذف یک یا چند داده) این داده‌ها می‌توانند روی حافظه دستگاه کاربر (localStorage) ذخیره شود تا زمانی که کاربر آنلاین شد، آن تغییرات با سرور هماهنگ شود که در انتهای همین صفحه توضیح داده شده است.

سرویس محبوب Gmail (ایمیل شرکت گوگل) در بخش موبایل خود، از همین حالت استفاده کرده است (منبع) یعنی در زمانی که کاربر با موبایل/تبلت وارد جیمیل می‌شود، امکان کار کردن حتی به صورت آفلاین را نیز دارا خواهد بود.

مراحل تهیه برنامه به صورت آفلاین

1. تهیه مانیفست فایل‌های آفلاین
manifest لیستی از فایل‌هایی است که قرار است کش شوند و ساختار درون آن، چیزی شبیه این خواهد بود:
CACHE MANIFEST

CACHE:

# pages
myPage.html
/about
?part=calendar

# styles & scripts
myStyle.css
myJavascript.js
http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js

# pictures & fonts
*.jpg
myImage.png
asset/fonts/alireza.ttf

FALLBACK:
/ /offline.html

NETWORK:
Images/logo.png
get-rating.php
*
در این فایل، لازم است در خط اول، با حروف بزرگ انگلیسی عبارت CACHE MANIFEST آورده شده و سپس آدرس فایل‌هایی که مرورگر باید cache کند، آورده شده است. در صورتی که بخواهید پس از عبارت CACHE MANIFEST بلافاصله نام فایل‌های موردنیاز را ذکر کنید، عبارت CACHE: ضروری نیست اما اگر بخواهید در بخش دیگری از مانیفست غیر از ابتدای آن، نام فایل‌هایتان را ذکر کنید که لازم است.
همچنین همانطور که در کد فوق می‌بینید؛ این فایل‌ها لازم نیست حتما تحت دامنه خودتان باشند و می‌توانید موارد استاتیک موجود در Url های دیگر را نیز در مانیفیست ذکر کنید.
علامت # در ابتدای خط برای افزودن توضیح و کامنت اضافی است. درج خط خالی جدید (Enter) نیز بلااشکال است.
خط بعد از FALLBACK: نیز برای تعریف فایل جایگزین برای مواردی است که در کش براوزر ذخیره نشده. در کد فوق، عبارت / /offilne.html به براوزر می‌گوید که در دسترس نبودن هر فایلی که مسیرش با / شروع می‌شود (یعنی همه فایل‌های تحت آن دامنه/زیردامنه)، فایل offline.html را به جای آن نمایش دهد.
فایل‌هایی که پس از خط حاوی NETWORK: درج شوند، در حالت آفلاین قابل دسترس نیستند براوزر هم تلاشی برای کش کردن و گرفتن آنها نمی‌کند.
همچنین همانطور که می‌بینید، می‌توان از علامت * نیز برای تطبیق بر «هر چیزی» استفاده کرد.
پس از نوشتن نام تمام فایل‌ها، آن را در یک فایل با پسوندی دلخواه (مثلا manifest) ذخیره کنید.
نکته: دقت کنید که فقط فایل‌هایی قابل لیست و کش شده هستند که با روش GET دریافت می‌شوند و لذا فایل‌هایی که با روش POST دریافت می‌شوند، قابل کش شدن نیستند چون براوزر فایل‌های لیست شده در مانیفست را با روش GET درخواست می‌دهد و سپس کش می‌کند.
2. تنظیم صفحه وب جهت ارجاع به مانیفست
پس از تهیه فایل مانیفست، لازم است آدرس فایل مانیفست به براوزر اعلام شود تا براوزر بتواند لیست فایل‌های لازم برای کار کردن برنامه در حالت آفلاین را ببیند. بدین منظور کافی است در تگ html یک مشخصه جدید به نام manifest اضافه کنید:
<!DOCTYPE html>
<html manifest="alireza.manifest">
دقت کنید که برخی براوزرها مانند سایر فایل‌ها، ممکن است به صورت پیش‌فرض فایل manifest را برای مدتی کش کنند که در اینصورت (مثل فایل css, js) بهترین راه برای فهماندن تغییر فایل manifest به مرورگر کاربر، تغییر نام داینامیک آن است.
همچنین دقت کنید که اگر برنامه آفلاین شما حاوی بیش از یک صفحه است، لازم است مانیفست فوق در تمام صفحات ذکر شود. به عبارت دیگر کافی نیست که فقط در home page تان مانیفست را اضافه کنید و در صفحات دیگر (که در مانیفست گفته شده) مانیفست را اضافه نکنید. به عبارت دیگر صفحاتی که مانیفست ندارند، در حالت آفلاین قابل دسترس نیستند حتی اگر در مانیفست صفحات آفلاین نام آنها ذکر شده باشد.
نکته: در صورتی که براوزر هنگام درخواست فایل مانیفست، با خطای 404 یا 410 مواجه شود، کش را پاک خواهد کرد.
نکته: در صورتی که خطایی در ساختار فایل مانیفست شما باشد، کش انجام نخواهد شد.
3. تنظیم سرور
فایل مانیفست می‌تواند هر پسوندی داشته باشد اما سرور باید به گونه‌ای تنظیم شود که فایل manifest را با MimeType خاصی (text/cache-manifest) سرو کند و همچنین آن را روی کلاینت کش نکند. مثلا اگر کارساز وب شما Apache است، و فایل‌های مانیفست شما با پسوند manifest سرو می‌شود، می‌توان در htaccess این‌گونه نوشت:
AddType text/cache-manifest .manifest
ExpiresActive On
ExpiresDefault "access"
4. کنترل سمت کاربر با js

بخش مهم و اعظم کار اینجاست. در این خصوص اجمالا نکاتی گفته می‌شود و برای فراگیری بهتر این بخش و تکنیک‌های آن، به لینک‌های انتهای مطلب، مراجعه کنید.

با شرط زیر می‌توان به سادگی چک کرد که آیا مرورگر کاربر، از حالت آفلاین پشتیبانی می‌کند یا خیر:

if(window.applicationCache) {
    // براوزر کاربر از حالت آفلاین پشتیبانی می‌کند
}

این کار می‌تواند فوایدی داشته باشد. مثلا می‌توانید در صورت پشتیبانی نکردن براوزر کاربر از حالت آفلاین، به او پیغام خاصی نمایش دهید یا برخی کدهای خاص مربوط به کار با حالت آفلاین را، ذیل شرط فوق قرار دهید.
همچنین در صورتی که مرورگر از حالت آفلاین هم پشتیبانی می‌کند، رویدادهای offline و online نیز در صفحه قابل تعریف هستند که در برنامه‌های آفلاین بسیار پرکاربرد هستند. به عبارتی دیگر، زمانی که براوزر آفلاین می‌شود (اتصالش به اینترنت قطع است) رویداد offline اجرا می‌شود و می‌توان تصمیمات خاصی گرفت و برخی کارکردهای اجزاء صفحه را تغییر داد:

window.addEventListener("online", function(e) {
    // همین الآن! براوزر به اینترنت دسترسی پیدا کرد و آنلاین شد
}, true);
window.addEventListener("offline", function(e) {
    // همین الآن! اتصال براوزر به اینترنت قطع شد و آفلاین شد
}, true);

پس از لود DOM، با خواندن پراپرتی onLine از آبجکت navigator می‌توان تشخیص داد که صفحه فعلی در حالت آنلاین لود شده یا در حالت آفلاین؟

$(function(){ // DOM Loaded...
    if(navigator.onLine)
    {
        // صفحه در حالت آنلاین لود شده است
    }
    else
    {
        // صفحه در حالت آفلاین لود شده است
    }
});
البته با کمک درخواست ajax ی نیز به سادگی می‌توان در ابتدای لود صفحه یا بعد از آن، آنلاین بودن/نبودن را چک کرد که نمونه کد آن در لینک آموزشی اول در انتهای مطلب قابل مشاهده است.

با کمک پراپرتی status از آبجکت window.applicationCache می‌توان وضعیت کش شدن/نشدن/بودن و ... را کشف کرد:

function getCacheStatus()
{
  switch (window.applicationCache.status) {
    case window.applicationCache.UNCACHED: // UNCACHED == 0
      return 'کش انجام نشده است';
      break;
    case window.applicationCache.IDLE: // IDLE == 1
      return 'بیکار';
      break;
    case window.applicationCache.CHECKING: // CHECKING == 2
      return 'در حال چک کردن';
      break;
    case window.applicationCache.DOWNLOADING: // DOWNLOADING == 3
      return 'در حال دانلود';
      break;
    case window.applicationCache.UPDATEREADY:  // UPDATEREADY == 4
      return 'آپدیت آماده است';
      break;
    case window.applicationCache.OBSOLETE: // OBSOLETE == 5
      return 'کش منسوخ شده و از بین است';
      break;
    default:
      return 'وضعیت نامشخص';
      break;
  };
}

می‌توان در صورت آماده بودن محتویات جدید، به کاربر اطلاع داد تا صفحه براوزرش رفرش شود و برنامه آفلاین جدید نمایش داده شود:

window.addEventListener('load', function(){
  window.applicationCache.addEventListener('updateready', function(){
    if (window.applicationCache.status == window.applicationCache.UPDATEREADY)
      // براوزر محتویات جدید را دانلود کرده است
      if (confirm('نسخه جدیدی از برنامه آماده شده، آیا مایل به رفرش صفحه هستید؟'))
        window.location.reload();
  }, false);

}, false);

8 رویداد (event) مهمی که در رابطه با کار با کش آفلاین می‌توان استفاده کرد:

// اگر برای آپدیت چک شود، این رویداد اجرا می‌شود
window.applicationCache.addEventListener('checking', handleCacheEvent, false);

// اگر آپدیتی یافت شود و براوزر شروع به دانلود آن کند، این رویداد اجرا می‌شود
window.applicationCache.addEventListener('downloading', handleCacheEvent, false);

// مانیفست یافت نشد (خطای 404 یا 410) یا اینکه در حین دانلود، مانیفست تغییر کرده
window.applicationCache.addEventListener('error', handleCacheError, false);

// پس از اولین دانلود مانیفست اجرا می‌شود
window.applicationCache.addEventListener('noupdate', handleCacheEvent, false);

// اگر مانیفست یافت نشود (خطای 404 یا 410) این رویداد اجرا می‌شود و کش خود به خود حذف می‌شود
window.applicationCache.addEventListener('obsolete', handleCacheEvent, false);

// این رویداد زمانی اجرا می‌شود که یک یا چند فایل لیست شده در مانیفست، در حال دانلود باشد
window.applicationCache.addEventListener('progress', handleCacheEvent, false);

// زمانی که آپدیت فایل‌های داخل مانیفست دانلود شده باشد، این رویداد اجرا می‌شود
window.applicationCache.addEventListener('updateready', handleCacheEvent, false);

فرم‌ها در حالت آفلاین

یکی از مسائلی که در حالت آفلاین باید درنظر گرفته شود، فرم‌های سایت است. اگر فرم می‌تواند بر اساس اطلاعات کش شده برای حالت آفلاین کار کند که مشکلی نیست. اما اگر فرم قرار است مثلا در یک دیتابیس بزرگ سمت سرور جستجو کند که حتما نیاز به سرور دارد، لازم است فرم را غیرفعال یا حتی مخفی کنید و پیغامی هم نمایش دهید که در حالت آفلاین امکان استفاده از فلان فرم جستجو نیست. اما گاهی یک فرم برای جستجو نیست بلکه برای مثلا اضافه کردن یک کامنت یا ویرایش یک مطلب است. در این حالت هم راه ساده آن است که در حالت آفلاین آن فرم را غیرفعال یا مخفی کنید اما راه بهتر که کدنویسی بیشتری هم نیاز دارد این است که به کاربر اجازه کار با فرم را در حالت آفلاین بدهیم و موارد درج‌شده در فرم را در localStorage ذخیره کنیم:

$('#myForm').submit(function(e){
  e.preventDefault();
  var data = $(this).serialize();
  if (navigator.onLine)
    $.post('/api', data);
  else
  {
    var submissions = JSON.parse(localStorage.getItem('submissions') || '[]');
    submissions.push(data);
    localStorage.setItem('submissions', JSON.stringify(submissions));
  }
});

سپس در رویداد مربوط به زمان آنلاین شدن (که در بالا اشاره شد) ارسال موارد ذخیره شده در localStorage به سرور را انجام دهیم:

window.addEventListener('online', function () {
  var submissions = JSON.parse(localStorage.getItem('submissions'));
  var promises = submissions.map(function (data) {
      return $.post('/api', data).done(function () {
        submissions.splice(submissions.indexOf(data), 1);
      });
    });
  $.when.apply($, promises).done(function () {
    localStorage.setItem('submissions', JSON.stringify(submissions));
  });
}, false);

افزودن وب‌اپ شما به صفحه اصلی موبایل کاربر

زمانی که وب‌اپلیکیشن در حالت آفلاین هم عملکردی تعریف‌شده دارد، شبیه یک اپلیکیشن تحت موبایل خواهد بود. تنها فرق‌ش این است که کاربر برای استفاده از آن لازم است وارد براوزر شود. برای بهبود روش ورود به یک اپلیکیشن با قابلیت کارکرد آفلاین، براوزرهای رایج (کروم و فایرفاکس) در نسخه موبایل، گزینه Add to home screen را دارند. با کلیک کاربر روی این گزینه از منوهای براوزر، یک میان‌بُر (Shortcut) به صفحه اصلی (Desktop) موبایل کاربر اضافه می‌شود. درست شبیه سایر شورتکات‌هایی که به برنامه‌های نصب شده روی موبایل هست.
تابحال مجبور بودیم همین توضیح فوق را برای کاربر بنویسیم تا این کار را دستی انجام دهد. اما هم‌اکنون پرمخاطب‌ترین مرورگر (کروم) این امکان را فراهم کرده که به سادگی می‌توانید پنجره‌ای کوچک (Prompt) به کاربر نمایش دهید تا پس از تایید (OK) کردن آن، میان‌بُر برنامه‌ی آفلاین شما به صفحه موبایل کاربر اضافه شود و با این کار، وب‌اپلیکیشن بیش از پیش شبیه یک اپ تحت سیستم‌عامل می‌شود.
در این مقاله به توضیح کامل در این باره پرداخته شده است...

مطالب آموزشی به همراه نمونه کد و توضیحات مفصل‌تر


یادداشت‌های مرتبط
  1. نمودارها در صفحات وب
  2. نقشه Google در سایت شما
  3. ابرکوکی و ذخیره ساز جدید HTML5
  4. انیمیشن با CSS
  5. روش های بهبود کیفیت آپلود فایل ها از طریق فرم های صفحات وب
  6. کار با قابلیت Page Visibility و کاربردهای آن
  7. اعتبارسنجی و شکل دهی فرم ها با استفاده از html5
  8. کشیدن و انداختن (رها کردن)
  9. ادیتورهای محتوای غنی شده برای صفحات وب
  10. html نسخه 5
  11. پخش کننده های فایل صوتی تصویری در صفحات وب
  12. برنامه نویسی اندروید
  13. پایگاه داده در جاوا اسکریپت
  14. کار با تصاویر در سمت کاربر
  15. نمونه کارهایی با اچ تی ام ال پنچ

مدیریت

نام وسیله

اعتبار ورود

نام کاربری

رمز عبور

رمز یکبارمصرف

... لیست تمام آموزش‌ها

تبلیغات

ربات‌های تلگرامی:
مجموعه ربات‌های تلگرامی ما برای ساده‌تر کردن کار با تلگرام و مدیریت کانال
دامنه‌های فروشی:
دامنه‌های زیر مربوط به ما یا مشتریان ماست که قابل واگذاری هستند. در صورت تمایل به داشتن یکی از آنها، با این اکانت تلگرامی مکاتبه نمایید.

دامنه‌هایی که می‌تواند مصرف تخصصی داشته باشد:
AnyDesk.ir, Firebase.ir, Angularjs.ir, 9px.ir alAdmin.ir, iQore.ir notion.ir, 3dn.ir,

دامنه‌هایی که می‌تواند مصرف فرهنگی/مذهبی داشته باشد:
mavaez.ir, 2aha.ir, babolelm.ir, mahjoor.ir

دامنه‌هایی که می‌تواند مصرف شخصی/عمومی داشته باشد:
azizami.ir, 90blog.ir