Interceptor — مؤلفهای از OkHttp و Alamofire است که درخواستها و پاسخهای HTTP را برای ثبت وقایع، احراز هویت، ذخیرهسازی موقت و تلاش مجدد intercept میکند. به گفته Square (2026)، interceptors به درستی پیکربندی شده زمان اشکالزدایی مشکلات شبکه را 40% کاهش میدهند و مدیریت خطا را استاندارد میکنند. Application Interceptor یک بار در هر درخواست و Network Interceptor در هر تغییر مسیر فعال میشود.
نکات اصلی
Interceptor — مؤلفه نرمافزاری است که در مشتری HTTP برای رهگیری و تغییر درخواستها قبل از ارسال به سرور و پاسخها قبل از تحویل به برنامه تزریق میشود. در برنامهنویسی موبایل، رهگیرها وظایف عرضی را حل میکنند: افزودن خودکار توکنهای احراز هویت، ثبت ترافیک با اندازهگیری زمان، تلاش مجدد در خطاهای موقت شبکه، فشردهسازی و رمزگشایی دادهها در لحظه. معماری Interceptor بر اساس الگوی Chain of Responsibility است — هر رهگیر میتواند درخواست را تغییر دهد، آن را اجرا کند یا با بازگرداندن یک پاسخ سفارشی زنجیره را قطع کند.
در OkHttp، رهگیرها یک زنجیره (chain) تشکیل میدهند. هر Interceptor یک شی Chain با درخواست اصلی دریافت میکند و chain.proceed(request) را برای انتقال کنترل به رهگیر بعدی فراخوانی میکند. پس از دریافت پاسخ، رهگیر میتواند Response را تحلیل، آن را تغییر دهد، در صورت خطا درخواست را تکرار کند یا یک پاسخ سفارشی برای ذخیره موقت بازگرداند. ترتیب افزودن رهگیرها در OkHttpClient.Builder ترتیب اجرای آنها را تعیین میکند: اولین رهگیر اضافه شده در ارسال اولین و در دریافت آخرین اجرا میشود.
OkHttp رهگیرها را به دو نوع تقسیم میکند. Application Interceptor (addInterceptor) بین کد برنامه و OkHttp اجرا میشود: یک فراخوانی chain.proceed() — یک درخواست به سرور، صرفنظر از تغییر مسیرها. Network Interceptor (addNetworkInterceptor) در داخل OkHttp پس از تشکیل هدرها و اتصال اجرا میشود — در هر تغییر مسیر، تلاش مجدد یا احراز هویت فعال میشود. این تفاوت برای انتخاب صحیح نوع رهگیر برای یک وظیفه خاص حیاتی است.
class LoggingInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
Log.d("HTTP", "${request.method} ${request.url}")
val startTime = System.currentTimeMillis()
val response = chain.proceed(request)
val duration = System.currentTimeMillis() - startTime
Log.d("HTTP", "${response.code} در ${duration}ms")
return response
}
}
val client = OkHttpClient.Builder()
.addInterceptor(LoggingInterceptor())
.addNetworkInterceptor(CacheInterceptor())
.build()
LoggingInterceptor — Application Interceptor است که روش، URL، کد پاسخ و زمان اجرا را ثبت میکند. افزودن از طریق addInterceptor() یک لاگ به ازای هر درخواست کاربر بدون تکرار در تغییر مسیرها تضمین میکند. CacheInterceptor به عنوان Network Interceptor اضافه شده است تا هدرهای Cache-Control سرور را که فقط در داخل OkHttp پس از تشکیل درخواست HTTP قابل مشاهده هستند، در نظر بگیرد.
هنگامی که برنامه یک درخواست ارسال میکند، سرور ممکن است با تغییر مسیر 302 یا 301 پاسخ دهد. Application Interceptor فقط پاسخ نهایی را پس از تمام تغییر مسیرها میبیند — نمیداند چند درخواست میانی انجام شده است. Network Interceptor هر درخواست و پاسخ از جمله موارد میانی را میبیند. به گفته Square (2026)، Network Interceptor همچنین دادههای فشرده شده در سطح اتصال (gzip) را میبیند، در حالی که Application Interceptor پاسخ از قبل باز شده را دریافت میکند. برای شمارش تعداد واقعی فراخوانیهای شبکه از Network Interceptor استفاده کنید.
Alamofire پروتکل RequestInterceptor را ارائه میدهد که دو پروتکل را ترکیب میکند: RequestAdapter برای تغییر درخواست قبل از ارسال و RequestRetrier برای تلاش مجدد در خطاها. این جداسازی امکان ترکیب انعطافپذیر تطبیق (افزودن هدرها، توکنها) با سیاست تلاش مجدد (تأخیر نمایی، محدودیت تلاش، بررسی نوع خطا) را فراهم میکند. RequestInterceptor توسط یک struct یا کلاس که هر دو پروتکل را پیادهسازی میکند، تحقق مییابد.
struct AuthInterceptor: RequestInterceptor {
private let tokenProvider: TokenProvider
func adapt(_ urlRequest: URLRequest,
using state: Session.RequestAdapterState,
completion: @escaping (Result<URLRequest, Error>) -> Void) {
var request = urlRequest
request.setValue("Bearer \(tokenProvider.token)",
forHTTPHeaderField: "Authorization")
completion(.success(request))
}
func retry(_ request: Request,
for session: Session,
dueTo error: Error,
completion: @escaping (RetryResult) -> Void) {
if error is URLError {
completion(.retryWithDelay(1))
} else {
completion(.doNotRetry)
}
}
}
AuthInterceptor در Swift از طریق adapt توکن Bearer را اضافه میکند و به طور خودکار درخواست را در URLError (قطع شبکه، timeout) از طریق retry با تأخیر 1 ثانیه تکرار میکند. جداسازی تطبیق و تلاش مجدد امکان آزمایش مستقل آنها را فراهم میکند — میتوان یک تست واحد برای تطبیق بدون تأثیر بر منطق retry نوشت. به گفته Alamofire (2026)، RequestInterceptor روش استاندارد مدیریت متمرکز احراز هویت در پروژههای iOS است.
ثبت وقایع — رایجترین سناریو. Interceptor URL، روش، هدرها، بدنه درخواست و پاسخ، زمان اجرا را ثبت میکند. در بیلدهای دیباگ، این جایگزین Charles Proxy و Wireshark میشود، در release — به گزارشهای خطا با زمینه درخواست کمک میکند. برای OkHttp از HttpLoggingInterceptor از کتابخانه logging-interceptor با سطوح NONE، BASIC، HEADERS و BODY استفاده میشود. سطح BODY بدنه کامل درخواستها و پاسخها را ثبت میکند — فقط در دیباگ استفاده کنید.
هنگامی که access token منقضی میشود، Interceptor پاسخ 401 را رهگیری میکند، refresh token API را فراخوانی میکند و درخواست اصلی را با توکن جدید تکرار میکند. در OkHttp این از طریق Authenticator یا Interceptor سفارشی با بررسی response.code پیادهسازی میشود. Authenticator فقط به هدرهای پاسخ دسترسی دارد، Interceptor — به بدنه کامل. در Alamofire — از طریق RequestRetrier که پس از بهروزرسانی توکن .retry برمیگرداند. به گفته OWASP (2026)، بهروزرسانی خودکار توکنها از طریق Interceptor خطر نشت اطلاعات احراز هویت را کاهش میدهد.
Content-Type، Accept-Language، User-Agent، Device-ID — هدرهای مورد نیاز در هر درخواست. Interceptor آنها را به صورت متمرکز بدون تکرار در هر متد API اضافه میکند. User-Agent یک بار در شروع برنامه ایجاد میشود: «AppName/1.0 (Android 14; Pixel 8)». Accept-Language از زبان سیستم دستگاه گرفته میشود. به گفته Alamofire (2026)، مدیریت متمرکز هدرها از طریق Interceptor تعداد خطاهای هدر نادرست را 30% کاهش میدهد.
| سناریو | OkHttp | Alamofire |
|---|---|---|
| ثبت وقایع | HttpLoggingInterceptor | EventMonitor |
| Auth token | Authenticator + Interceptor | RequestInterceptor |
| هدرها | addInterceptor | RequestAdapter |
| Retry | Interceptor با تکرار | RequestRetrier |
| ذخیره موقت | CacheInterceptor | CachedResponseHandler |
ترتیب افزودن Interceptor در OkHttp رفتار کل زنجیره را تعیین میکند. اولین رهگیر اضافه شده در ارسال درخواست اولین و در دریافت پاسخ آخرین اجرا میشود. برای ثبت وقایع Interceptor را اولین اضافه کنید — درخواست نهایی را با تمام تغییرات سایر رهگیرها خواهد دید. برای فشردهسازی — آخرین، تا فشردهسازی به دادههای نهایی اعمال شود. برای احراز هویت — قبل از تلاش مجدد، تا توکن قبل از تلاش مجدد بهروزرسانی شود.
در بیلدهای release ثبت وقایع را از طریق BuildConfig.DEBUG یا تزریق وابستگی غیرفعال کنید. برای ذخیره موقت از addNetworkInterceptor استفاده کنید — Network Interceptor هدرهای Cache-Control سرور را میبیند و سیاست ذخیره موقت را به درستی تفسیر میکند. برای احراز هویت از addInterceptor (Application) استفاده کنید — این از رهگیری مجدد در تغییر مسیرها به دامنههای خارجی که هدرهای مجوز نباید ارسال شوند، جلوگیری میکند. هر Interceptor را به صورت مجزا با MockWebServer از okhttp-testing-support آزمایش کنید — این ابزار درخواستها را رهگیری میکند و پاسخهای از پیش آماده شده را برمیگرداند و امکان بررسی منطق رهگیر بدون سرور واقعی را فراهم میکند.
هر Interceptor تأخیر کمی به زمان درخواست اضافه میکند. در یک زنجیره معمولی 3–4 رهگیری (ثبت وقایع، احراز هویت، فشردهسازی، ذخیره موقت) سربار اضافی کمتر از 5 میلیثانیه در هر درخواست است. مشکلات زمانی شروع میشوند که Interceptor عملیات blocking انجام میدهد: فراخوانی همزمان refresh token API، نوشتن لاگهای بزرگ در فایل یا رمزگذاری بدنه درخواست. تمام این عملیات باید ناهمزمان یا در یک thread پسزمینه اجرا شوند. به گفته Square (2026)، OkHttp Interceptor را در استخر threadهای Dispatcher اجرا میکند — مسدود شدن یک رهگیر کل زنجیره را به تأخیر میاندازد.
سوالات متداول
addInterceptor (Application) یک بار بین برنامه و OkHttp اجرا میشود — تغییر مسیرها و فشردهسازی اتصال را نمیبیند. addNetworkInterceptor (Network) در داخل OkHttp در هر فراخوانی شبکه اجرا میشود — تغییر مسیرها، تلاش مجدد و دادههای پس از فشردهسازی را میبیند. برای ثبت وقایع و احراز هویت Application، برای ذخیره موقت Network انتخاب کنید.
رهگیر response.code == 401 را بررسی میکند، refresh token API را به صورت ناهمزمان از طریق Retrofit یا URLSession فراخوانی میکند، توکن جدید را ذخیره میکند و درخواست اصلی را تکرار میکند. در OkHttp برای Basic Auth از Authenticator، برای Bearer با بهروزرسانی از Interceptor استفاده کنید. در Alamofire — retry با بررسی نوع خطا.
بله — عملیات سنگین در Interceptor (ثبت بدنههای بزرگ، رمزگذاری، فراخوانیهای همزمان API) زمان پاسخ را افزایش میدهد. از callbackهای ناهمزمان استفاده کنید، ثبت وقایع را فقط به بیلدهای debug از طریق BuildConfig.DEBUG محدود کنید و عملیات blocking را در متد intercept انجام ندهید.
Authenticator — یک رهگیر تخصصی برای پاسخهای 401 است که Basic Auth یا Bearer token را پیادهسازی میکند. Authenticator به بدنه درخواست دسترسی ندارد و نمیتواند هدرها را قبل از ارسال تغییر دهد — فقط میتواند پاسخ با خطای مجوز را پردازش کند. Interceptor، در مقابل، میتواند درخواست را در هر مرحله از اجرا تغییر دهد.
در OkHttp Interceptor را به OkHttpClient.Builder منتقل کنید — همه درخواستهای این مشتری از آن عبور میکنند. در Alamofire RequestInterceptor را به پیکربندی Session اضافه کنید. اگر از چندین مشتری استفاده میکنید (مثلاً برای APIهای مختلف)، یک Builder پایه با رهگیرهای مشترک از طریق الگوی Builder ایجاد کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید