Interceptor — nó là gì, các loại interceptor OkHttp và Alamofire

Tác giả: IT Sectr Đã đăng: 2026-03-08 Thời gian đọc: 8 phút

Interceptor là một thành phần của OkHttp và Alamofire giúp chặn các yêu cầu và phản hồi HTTP để ghi log, xác thực, lưu vào bộ nhớ đệm và thử lại. Theo Square (2026), các interceptor được cấu hình đúng cách giúp giảm 40% thời gian gỡ lỗi mạng và chuẩn hóa việc xử lý lỗi. Application Interceptor chạy một lần cho mỗi yêu cầu, còn Network Interceptor chạy cho mỗi lần chuyển hướng.

Điểm chính

  • Interceptor — một interceptor yêu cầu và phản hồi HTTP trong OkHttp và Alamofire cho các tác vụ xuyên suốt.
  • Application Interceptor thực thi một lần trước và sau yêu cầu giữa ứng dụng và OkHttp.
  • Network Interceptor kích hoạt ở mỗi lần chuyển hướng và thử lại trong OkHttp.
  • RequestInterceptor trong Alamofire kết hợp việc thích ứng yêu cầu và thử lại.
  • Chain.proceed() — phương thức chính của OkHttp truyền yêu cầu dọc theo chuỗi interceptor.

Interceptor là gì?

Interceptor là một thành phần phần mềm được tiêm vào trình khách HTTP để chặn và sửa đổi các yêu cầu trước khi gửi đến máy chủ và các phản hồi trước khi đến ứng dụng. Trong phát triển di động, interceptor xử lý các tác vụ xuyên suốt: tự động tiêm mã thông báo xác thực, ghi log lưu lượng với đo thời gian, thử lại khi lỗi mạng tạm thời, nén và giải mã dữ liệu ngay trong quá trình. Kiến trúc Interceptor dựa trên mô hình Chain of Responsibility — mỗi interceptor có thể sửa đổi yêu cầu, thực thi nó hoặc ngắt chuỗi bằng cách trả về phản hồi tùy chỉnh.

Cách chuỗi interceptor hoạt động

Trong OkHttp, các interceptor tạo thành một chuỗi. Mỗi Interceptor nhận một đối tượng Chain với yêu cầu gốc và gọi chain.proceed(request) để chuyển quyền điều khiển cho interceptor tiếp theo. Sau khi nhận được phản hồi, interceptor có thể phân tích Response, sửa đổi nó, thử lại yêu cầu khi có lỗi hoặc trả về phản hồi tùy chỉnh cho bộ nhớ đệm. Thứ tự thêm interceptor vào OkHttpClient.Builder xác định thứ tự thực thi của chúng: interceptor được thêm đầu tiên sẽ thực thi đầu tiên khi gửi và cuối cùng khi nhận.

Interceptor trong OkHttp: Application và Network

OkHttp phân chia interceptor thành hai loại. Application Interceptor (addInterceptor) thực thi giữa mã ứng dụng và OkHttp: một lần gọi chain.proceed() — một yêu cầu đến máy chủ, bất kể chuyển hướng. Network Interceptor (addNetworkInterceptor) thực thi bên trong OkHttp sau khi hình thành tiêu đề và kết nối — nó kích hoạt ở mỗi lần chuyển hướng, thử lại hoặc cố gắng xác thực. Sự phân biệt này rất quan trọng để chọn đúng loại interceptor cho một nhiệm vụ cụ thể.

kotlin
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} in ${duration}ms")
        return response
    }
}

val client = OkHttpClient.Builder()
    .addInterceptor(LoggingInterceptor())
    .addNetworkInterceptor(CacheInterceptor())
    .build()

LoggingInterceptor — một Application Interceptor ghi log phương thức, URL, mã phản hồi và thời gian thực thi. Thêm nó qua addInterceptor() đảm bảo một log cho mỗi yêu cầu người dùng mà không trùng lặp khi chuyển hướng. CacheInterceptor được thêm dưới dạng Network Interceptor để tính đến các tiêu đề Cache-Control từ máy chủ, chỉ hiển thị bên trong OkHttp sau khi yêu cầu HTTP được hình thành.

Sự khác biệt giữa các loại trong thực tế

Khi ứng dụng thực hiện một yêu cầu, máy chủ có thể phản hồi bằng chuyển hướng 302 hoặc 301. Application Interceptor chỉ thấy phản hồi cuối cùng sau tất cả các lần chuyển hướng — nó không biết có bao nhiêu yêu cầu trung gian đã được thực hiện. Network Interceptor thấy mỗi yêu cầu và phản hồi, bao gồm cả các yêu cầu trung gian. Theo Square (2026), Network Interceptor cũng thấy dữ liệu được nén ở cấp độ kết nối (gzip), trong khi Application Interceptor nhận được phản hồi đã được giải nén. Để đếm số lượng cuộc gọi mạng thực tế, hãy sử dụng Network Interceptor.

Alamofire RequestInterceptor

Alamofire cung cấp giao thức RequestInterceptor, kết hợp hai giao thức: RequestAdapter để sửa đổi yêu cầu trước khi gửi và RequestRetrier để thử lại khi có lỗi. Sự phân tách này cho phép kết hợp linh hoạt việc thích ứng (thêm tiêu đề, mã thông báo) với chính sách thử lại (backoff theo hàm mũ, giới hạn lần thử, kiểm tra loại lỗi). RequestInterceptor được triển khai bởi một cấu trúc hoặc lớp duy nhất tuân thủ cả hai giao thức.

swift
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 trên Swift thêm mã thông báo Bearer thông qua adapt và tự động thử lại yêu cầu khi URLError (mất mạng, hết thời gian) thông qua retry với độ trễ 1 giây. Việc tách riêng thích ứng và thử lại cho phép kiểm thử chúng một cách độc lập — bạn có thể viết bài kiểm thử đơn vị cho việc thích ứng mà không ảnh hưởng đến logic thử lại. Theo Alamofire (2026), RequestInterceptor là cách tiêu chuẩn để tập trung hóa việc quản lý xác thực trong các dự án iOS.

Các trường hợp sử dụng interceptor

Ghi log — trường hợp sử dụng phổ biến nhất. Interceptor ghi lại URL, phương thức, tiêu đề, nội dung yêu cầu và phản hồi cũng như thời gian thực thi. Trong các bản dựng debug, điều này thay thế Charles Proxy và Wireshark; trong các bản dựng release, nó hỗ trợ báo cáo sự cố với ngữ cảnh yêu cầu. OkHttp sử dụng HttpLoggingInterceptor từ thư viện logging-interceptor với các cấp độ NONE, BASIC, HEADERS và BODY. Cấp độ BODY ghi log toàn bộ nội dung yêu cầu và phản hồi — chỉ sử dụng trong debug.

Xác thực và làm mới mã thông báo

Khi mã thông báo truy cập hết hạn, Interceptor chặn phản hồi 401, gọi API làm mới mã thông báo và thử lại yêu cầu ban đầu với mã thông báo mới. Trong OkHttp, điều này được triển khai thông qua Authenticator hoặc Interceptor tùy chỉnh với kiểm tra response.code. Authenticator chỉ có quyền truy cập vào tiêu đề phản hồi, trong khi Interceptor có quyền truy cập vào toàn bộ nội dung. Trong Alamofire — thông qua RequestRetrier, trả về .retry sau khi làm mới mã thông báo. Theo OWASP (2026), việc tự động làm mới mã thông báo qua Interceptor giảm nguy cơ rò rỉ thông tin xác thực.

Thêm tiêu đề chung

Content-Type, Accept-Language, User-Agent, Device-ID — các tiêu đề cần thiết trong mỗi yêu cầu. Interceptor thêm chúng một cách tập trung, không trùng lặp trong mỗi phương thức API. User-Agent được hình thành một lần khi khởi động ứng dụng: “AppName/1.0 (Android 14; Pixel 8)”. Accept-Language được lấy từ ngôn ngữ hệ thống của thiết bị. Theo Alamofire (2026), quản lý tiêu đề tập trung qua Interceptor giảm 30% lỗi tiêu đề không chính xác.

Kịch bảnOkHttpAlamofire
Ghi logHttpLoggingInterceptorEventMonitor
Mã xác thựcAuthenticator + InterceptorRequestInterceptor
Tiêu đềaddInterceptorRequestAdapter
Thử lạiInterceptor có thử lạiRequestRetrier
Bộ nhớ đệmCacheInterceptorCachedResponseHandler

Thực hành tốt nhất và thứ tự chuỗi

Thứ tự thêm Interceptors trong OkHttp xác định hành vi của toàn bộ chuỗi. Interceptor được thêm đầu tiên sẽ thực thi đầu tiên khi gửi yêu cầu và cuối cùng khi nhận phản hồi. Đối với ghi log, hãy thêm Interceptor đầu tiên — nó sẽ thấy yêu cầu cuối cùng với tất cả các sửa đổi từ các interceptor khác. Đối với nén, hãy thêm nó cuối cùng để việc nén được áp dụng cho dữ liệu cuối cùng. Đối với xác thực, hãy thêm nó trước khi thử lại để mã thông báo được làm mới trước lần thử tiếp theo.

Khuyến nghị cho bản dựng production

Trong các bản dựng release, hãy tắt ghi log thông qua BuildConfig.DEBUG hoặc tiêm phụ thuộc. Sử dụng addNetworkInterceptor cho bộ nhớ đệm — Network Interceptor thấy các tiêu đề Cache-Control từ máy chủ và diễn giải chính sách bộ nhớ đệm một cách chính xác. Đối với xác thực, hãy sử dụng addInterceptor (Application) — điều này ngăn chặn việc chặn lại khi chuyển hướng đến các miền bên thứ ba nơi không nên gửi tiêu đề ủy quyền. Kiểm thử từng Interceptor một cách riêng biệt bằng MockWebServer từ okhttp-testing-support — nó chặn các yêu cầu và trả về các phản hồi được chuẩn bị trước, cho phép bạn xác minh logic interceptor mà không cần máy chủ thực.

Hiệu suất Interceptor

Mỗi Interceptor thêm một độ trễ nhỏ vào thời gian yêu cầu. Trong một chuỗi điển hình gồm 3-4 interceptor (ghi log, xác thực, nén, bộ nhớ đệm), chi phí tăng thêm ít hơn 5 mili giây cho mỗi yêu cầu. Các vấn đề phát sinh khi Interceptor thực hiện các thao tác chặn: gọi API đồng bộ để làm mới mã thông báo, ghi các log lớn vào tệp hoặc mã hóa nội dung yêu cầu. Tất cả các thao tác này phải không đồng bộ hoặc được thực thi trong luồng nền. Theo Square (2026), OkHttp thực thi Interceptors trong nhóm luồng Dispatcher — việc chặn một interceptor sẽ làm trì hoãn toàn bộ chuỗi.

  • Thứ tự rất quan trọng — ghi log đầu tiên, xác thực trước khi thử lại, nén cuối cùng
  • Debug vs Release — HttpLoggingInterceptor chỉ trong bản dựng debug
  • Cách ly — mỗi Interceptor xử lý một tác vụ (Trách nhiệm đơn lẻ)
  • Bất đồng bộ — Interceptor chạy trên luồng nền của OkHttp, không chặn UI

Câu hỏi thường gặp

Sự khác biệt giữa addInterceptor và addNetworkInterceptor trong OkHttp là gì?

addInterceptor (Application) thực thi một lần giữa ứng dụng và OkHttp — nó không thấy chuyển hướng hoặc nén kết nối. addNetworkInterceptor (Network) thực thi bên trong OkHttp ở mỗi cuộc gọi mạng — nó thấy chuyển hướng, thử lại và dữ liệu sau khi nén. Chọn Application cho ghi log và xác thực, Network cho bộ nhớ đệm.

Interceptor tự động làm mới mã thông báo như thế nào?

Interceptor kiểm tra response.code == 401, gọi API làm mới mã thông báo bất đồng bộ qua Retrofit hoặc URLSession, lưu mã thông báo mới và thử lại yêu cầu ban đầu. Trong OkHttp, sử dụng Authenticator cho Basic Auth và Interceptor cho Bearer với làm mới. Trong Alamofire — sử dụng retry với kiểm tra loại lỗi.

Interceptor có thể làm chậm ứng dụng không?

Có — các thao tác nặng trong Interceptor (ghi log nội dung lớn, mã hóa, gọi API đồng bộ) làm tăng thời gian phản hồi. Sử dụng callback bất đồng bộ, giới hạn ghi log chỉ trong bản dựng debug qua BuildConfig.DEBUG và không thực hiện các thao tác chặn trong phương thức intercept.

Authenticator trong OkHttp là gì và khác gì so với Interceptor?

Authenticator là một interceptor chuyên dụng cho các phản hồi 401, triển khai Basic Auth hoặc Bearer token. Authenticator không có quyền truy cập vào nội dung yêu cầu và không thể sửa đổi tiêu đề trước khi gửi — nó chỉ xử lý phản hồi lỗi ủy quyền. Ngược lại, Interceptor có thể sửa đổi yêu cầu ở bất kỳ giai đoạn thực thi nào.

Làm thế nào để thêm cùng một Interceptor vào tất cả các yêu cầu?

Trong OkHttp, hãy truyền Interceptor vào OkHttpClient.Builder — tất cả các yêu cầu từ trình khách này đều đi qua nó. Trong Alamofire, hãy thêm RequestInterceptor vào cấu hình Session. Nếu bạn sử dụng nhiều trình khách (ví dụ, cho các API khác nhau), hãy tạo một Builder cơ sở với các interceptor chung bằng cách sử dụng mô hình Builder.

Tổng kết

  • Interceptor — cơ chế chặn yêu cầu và phản hồi HTTP dựa trên mô hình Chain of Responsibility.
  • OkHttp cung cấp hai loại: Application (một lần gọi cho mỗi yêu cầu) và Network (ở mỗi lần chuyển hướng và thử lại).
  • Alamofire tách riêng thích ứng (RequestAdapter) và thử lại (RequestRetrier) trong một RequestInterceptor duy nhất.
  • Các trường hợp sử dụng chính — ghi log, xác thực, tiêu đề, thử lại và lưu vào bộ nhớ đệm phản hồi HTTP.
  • Thứ tự thêm Interceptors vào Builder xác định trình tự thực thi: ghi log đầu tiên, nén cuối cùng.
  • Các bản dựng production yêu cầu tắt ghi log debug thông qua cờ BuildConfig và tiêm DI.
  • Một chuỗi interceptor được cấu hình tốt giảm thời gian gỡ lỗi mạng xuống 40% và chuẩn hóa việc xử lý lỗi.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm