Conditional GET: چیست، مکانیزم درخواست شرطی

نویسنده: IT Sectr منتشر شده: 2026-06-14 زمان مطالعه: 7 دقیقه

Conditional GET (درخواست GET شرطی) — مکانیزم HTTP که به کلاینت اجازه می‌دهد قبل از بارگذاری کامل، به‌روزرسانی منبع کش‌شده را بررسی کند. کلاینت یک درخواست GET با هدرهای If-None-Match (شامل ETag) یا If-Modified-Since (شامل تاریخ) ارسال می‌کند و اگر منبع تغییر نکرده باشد، سرور 304 Not Modified بدون بدنه پاسخ برمی‌گرداند. به گفته MDN Web Docs, 2025، درخواست‌های شرطی ترافیک شبکه سرورها و کلاینت‌ها را کاهش می‌دهند. 304 Not Modified — وضعیت HTTP کلیدی برای همگام‌سازی مؤثر برنامه‌های موبایل.

نکات اصلی

  • Conditional GET — درخواست HTTP با هدرهای If-None-Match یا If-Modified-Since برای بررسی به‌روزرسانی کش.
  • 304 Not Modified — پاسخ سرور که نشان می‌دهد منبع تغییر نکرده است. بدنه پاسخ منتقل نمی‌شود و ترافیک صرفه‌جویی می‌شود.
  • If-None-Match — هدر با ETag (هش نسخه) که بررسی دقیق در سطح محتوای منبع را فراهم می‌کند.
  • If-Modified-Since — هدر با تاریخ آخرین تغییر، پیاده‌سازی ساده‌تر اما دقت کمتر (دقت ۱ ثانیه).
  • کارایی — Conditional GET حجم داده‌ها را در همگام‌سازی برای منابع تغییرنیافته ۸۰–۹۵٪ کاهش می‌دهد.

Conditional GET در HTTP چیست؟

Conditional GET — یک درخواست GET است که شامل یک یا چند هدر شرطی می‌باشد که بر اساس آن سرور تصمیم می‌گیرد پاسخ کامل یا فقط وضعیت 304 Not Modified را برگرداند. هدف اصلی اجتناب از انتقال بدنه پاسخ در صورت عدم تغییر منبع از آخرین درخواست است. این یک مکانیزم اساسی کش HTTP است که در مشخصات RFC 7232 تعریف شده است.

برای برنامه‌های موبایل، Conditional GET یکی از مؤثرترین روش‌های بهینه‌سازی ترافیک شبکه است. سناریوی معمول: هنگام باز کردن برنامه، کلاینت یک سری درخواست‌های GET شرطی برای بارگذاری فید، پروفایل و تنظیمات ارسال می‌کند. اگر داده‌ها تغییر نکرده باشند، برنامه 304 دریافت می‌کند و از کپی محلی استفاده می‌کند. این کار میلی‌ثانیه طول می‌کشد نه ثانیه و ترافیک موبایل مصرف نمی‌کند.

بر اساس Google Web Fundamentals (2025)، پیاده‌سازی درخواست‌های GET شرطی در برنامه موبایل میانگین زمان بارگذاری را برای بازدیدهای مکرر ۴۰–۶۰٪ کاهش می‌دهد و مصرف ترافیک را برای صفحات با به‌روزرسانی نادر ۷۰–۹۰٪ کاهش می‌دهد. این اثر به ویژه در اتصالات کند (3G، Edge) محسوس است، جایی که هر بایت مهم است.

درخواست GET شرطی چگونه کار می‌کند

فرآیند شامل سه مرحله است. مرحله اول — کلاینت یک درخواست GET معمولی ارسال می‌کند، سرور منبع را همراه با هدرهای کش (ETag, Last-Modified) برمی‌گرداند. مرحله دوم — کلاینت منبع و اعتبارسنج‌های آن را به صورت محلی ذخیره می‌کند. مرحله سوم — در درخواست مجدد، کلاینت GET را با If-None-Match (برای ETag) و/یا If-Modified-Since (برای Last-Modified) ارسال می‌کند. سرور اعتبارسنج‌ها را بررسی می‌کند و اگر منبع تغییر نکرده باشد 304، در غیر این صورت 200 با داده‌های جدید پاسخ می‌دهد.

سرور در صورت وجود هر دو هدر از اولویت ETag بر Last-Modified استفاده می‌کند. این به دلیل این است که ETag اعتبارسنجی دقیق‌تری ارائه می‌دهد — هش محتوا با هر تغییری تغییر می‌کند، در حالی که Last-Modified دقت یک ثانیه دارد. اگر ETag مطابقت داشته باشد، سرور بلافاصله 304 را برمی‌گرداند بدون بررسی Last-Modified.

نمونه چرخه کامل Conditional GET در توالی درخواست‌ها:

kotlin
// مرحله ۱: درخواست اول — دریافت داده و ETag
GET /api/profile
Response: 200 OK
ETag: "33a64df551425fcc55e"
Body: { "name": "Alice" }

// مرحله ۲: تکرار درخواست — با If-None-Match
GET /api/profile
If-None-Match: "33a64df551425fcc55e"
Response: 304 Not Modified
// بدنه پاسخ وجود ندارد — از کپی محلی استفاده کنید

در درخواست دوم، سرور ETag را از If-None-Match با هش فعلی منبع مقایسه می‌کند. در صورت تطابق، 304 بدون بدنه برگردانده می‌شود — کلاینت به استفاده از داده‌های کش‌شده ادامه می‌دهد. این جوهر Conditional GET است: حداقل ترافیک با حداکثر به‌روزرسانی داده‌ها.

Conditional GET در مقابل GET معمولی

درخواست GET معمولی همیشه پاسخ کامل 200 OK را با بدنه برمی‌گرداند. حتی اگر منبع تغییر نکرده باشد، سرور همه داده‌ها را دوباره ارسال می‌کند. این برای منابع کوچک یا درخواست‌های نادر قابل قبول است، اما برای برنامه‌های موبایل با صدها درخواست در هر بار راه‌اندازی، چنین رویکردی منجر به مصرف بیش از حد ترافیک و باتری می‌شود.

Conditional GET سربار اضافی به صورت هدرها (معمولاً ۵۰–۲۰۰ بایت در هر درخواست) اضافه می‌کند، اما در پاسخ 304 کیلوبایت و مگابایت صرفه‌جویی می‌کند. هرچه منبع بزرگ‌تر باشد، درخواست شرطی مقرون‌به‌صرفه‌تر است. برای تصاویر، لیست‌های داده و اسناد JSON با اندازه ۱۰ کیلوبایت به بالا، Conditional GET از اولین درخواست مجدد به صرفه می‌شود.

مقایسه دو رویکرد:

پارامترGET معمولیConditional GET
ترافیک (بدون تغییر)پاسخ کاملفقط هدرها (~۲۰۰ بایت)
تأخیربارگذاری کاملمیلی‌ثانیه (304)
بار سرورتولید + انتقالفقط بررسی ETag
پیچیدگی پیاده‌سازیحداقلنیاز به ذخیره ETag
کارایی برای داده‌های بزرگکمزیاد

نمونه‌های پیاده‌سازی در Kotlin

بیایید یک پیاده‌سازی کامل Conditional GET را در Kotlin با استفاده از OkHttp و Room برای ذخیره ETag بررسی کنیم. برنامه لیست وظایف، وظایف را از سرور بارگذاری می‌کند و از درخواست‌های شرطی برای به حداقل رساندن ترافیک استفاده می‌کند. ETagها در پایگاه داده محلی برای حفظ بین جلسات ذخیره می‌شوند.

مخزن با Conditional GET در Kotlin:

kotlin
class TaskRepository(
    private val api: TaskApi,
    private val etagDao: EtagDao
) {
    suspend fun getTasks(): List<Task> {
        val savedEtag = etagDao.getEtag("tasks")

        val response = api.fetchTasks(
            ifNoneMatch = savedEtag
        )

        return when (response.code()) {
            304 -> taskDao.getAll() // از کش محلی
            200 -> {
                response.header("ETag")?.let {
                    etagDao.saveEtag("tasks", it)
                }
                val tasks = response.body() ?: emptyList()
                taskDao.replaceAll(tasks)
                tasks
            }
            else -> throw Exception(
                "Sync failed: ${response.code()}")
        }
    }
}

TaskRepository کد پاسخ را بررسی می‌کند: 304 به معنی عدم تغییر است و داده‌ها از کش محلی Room برگردانده می‌شوند. در 200، ETag جدید ذخیره شده و وظایف در پایگاه محلی به‌روزرسانی می‌شوند. این الگو استانداردی برای برنامه‌های موبایل با همگام‌سازی از طریق REST API است.

کاربرد Conditional GET در توسعه موبایل

Conditional GET به طور گسترده استفاده می‌شود در برنامه‌های موبایل برای بهینه‌سازی همگام‌سازی داده‌ها. سناریوهای اصلی: بارگذاری فید خبری (Twitter، Instagram به صورت دوره‌ای API را با If-None-Match پرس‌وجو می‌کنند)، به‌روزرسانی پروفایل کاربر، بارگذاری لیست اعلان‌ها و همگام‌سازی وظایف. در هر مورد، برنامه می‌تواند بدون بارگذاری مجدد داده‌ها، به‌روزرسانی آنها را بررسی کند.

برای برنامه‌های آفلاین-first، Conditional GET به عنوان مرحله اول همگام‌سازی عمل می‌کند. برنامه ابتدا درخواست‌های GET شرطی را برای تمام منابعی که از آخرین همگام‌سازی به صورت محلی تغییر کرده‌اند ارسال می‌کند. منابع با 304 نیاز به بارگذاری ندارند. پس از آن، برنامه PUT/POST را برای تغییرات محلی ارسال می‌کند. چنین رویکرد دو مرحله‌ای حداقل مصرف ترافیک را تضمین می‌کند.

در ترکیب با حل تعارض، Conditional GET امکان تشخیص مؤثر تعارضات را فراهم می‌کند. اگر کلاینت 200 با داده‌های جدید دریافت کرده است (منبع تغییر کرده)، اما کلاینت تغییرات محلی ارسال‌نشده دارد — یک تعارض ثبت می‌شود. کلاینت می‌تواند LWW را اعمال کند (تغییرات محلی از دست می‌روند) یا استراتژی ادغام را برای ترکیب تغییرات محلی و راه دور اجرا کند. به گفته Meta Engineering Blog (2025)، پیاده‌سازی Conditional GET در Messenger میانگین مصرف ترافیک همگام‌سازی را ۷۳٪ کاهش داد.

سؤالات متداول

درخواست Conditional GET چیست؟

Conditional GET — درخواست HTTP GET با هدرهای شرطی (If-None-Match, If-Modified-Since). اگر منبع تغییر نکرده باشد، سرور 304 Not Modified، در غیر این صورت 200 با داده‌های جدید برمی‌گرداند. این مکانیزم کش مؤثر است.

Conditional GET چه تفاوتی با درخواست معمولی دارد؟

GET معمولی همیشه پاسخ کامل با بدنه برمی‌گرداند. Conditional GET هدرهای بررسی نسخه (ETag، تاریخ) را اضافه می‌کند. اگر داده‌ها تغییر نکرده باشند، سرور 304 بدون بدنه پاسخ می‌دهد و ترافیک و زمان بارگذاری صرفه‌جویی می‌شود.

چگونه از Conditional GET برای کش استفاده کنیم؟

برای کش مؤثر ETag و Last-Modified را از هر پاسخ سرور در پایگاه داده محلی ذخیره کنید. در درخواست بعدی، آنها را در هدرهای If-None-Match و If-Modified-Since ارسال کنید. در 304 از داده‌های کش محلی استفاده کنید.

Conditional GET چگونه به صرفه‌جویی ترافیک کمک می‌کند؟

در پاسخ 304 سرور بدنه پاسخ را منتقل نمی‌کند — فقط هدرها (~۲۰۰ بایت). برای منبعی با اندازه ۵۰ کیلوبایت این به معنای صرفه‌جویی ۹۹.۶٪ ترافیک است. برای برنامه‌ای که ۵۰ بار در روز همگام‌سازی می‌کند، صرفه‌جویی به ده‌ها مگابایت در ماه می‌رسد.

آیا می‌توان از Conditional GET برای همگام‌سازی استفاده کرد؟

بله، این رویکرد استاندارد برای همگام‌سازی دلتا است. کلاینت به‌روزرسانی هر منبع را از طریق Conditional GET بررسی می‌کند، فقط منابع تغییر کرده را بارگذاری می‌کند و تغییرات محلی را ارسال می‌کند. این رویکرد در Twitter، Instagram، Telegram و اکثر APIهای مدرن استفاده می‌شود.

خلاصه

  • Conditional GET — مکانیزم HTTP برای بررسی به‌روزرسانی منابع کش‌شده از طریق هدرهای شرطی If-None-Match و If-Modified-Since.
  • 304 Not Modified — پاسخ سرور که نشان می‌دهد منبع تغییر نکرده است. بدنه پاسخ منتقل نمی‌شود و ترافیک و زمان بارگذاری صرفه‌جویی می‌شود.
  • ETag در مقابل Last-Modified — ETag دقیق‌تر است (هش محتوا)، Last-Modified ساده‌تر است (تاریخ). توصیه می‌شود هر دو را برای حداکثر کارایی ترکیب کنید.
  • صرفه‌جویی ترافیک — برای منابع تغییرنیافته، Conditional GET حجم داده‌های منتقل‌شده را ۷۰–۹۵٪ بسته به اندازه منبع کاهش می‌دهد.
  • کاربرد — مکانیزم استاندارد همگام‌سازی در Twitter، Instagram، Telegram و اکثر REST APIهای مدرن.
  • ادغام — در سمت کلاینت نیاز به ذخیره ETag در پایگاه داده محلی است، در سمت سرور — تولید و مقایسه ETag در هر درخواست.
  • توصیه — Conditional GET را برای همه endpointهای GET در API موبایل پیاده‌سازی کنید. این ارزان‌ترین روش بهینه‌سازی با بیشترین اثر برای کاربران است.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید