Dio: คืออะไรและคุณสมบัติของ HTTP client สำหรับ Flutter

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-03-07 เวลาอ่าน: 8 นาที

Dio คือ HTTP client ที่ทรงพลังสำหรับ Dart และ Flutter พัฒนาโดยวิศวกรชาวจีน Wenda Wang ไลบรารีนี้มี API ขั้นสูงพร้อมรองรับอินเตอร์เซพเตอร์ FormData การอัปโหลดไฟล์ และการยกเลิกคำขอ ตามข้อมูลจาก pub.dev, 2025 Dio เป็น HTTP client ที่ได้รับความนิยมมากที่สุดในระบบนิเวศ Flutter โดยมีดาวบน GitHub มากกว่า 8 พันดวง

ประเด็นสำคัญ

  • Dio — HTTP client ที่ทรงพลังสำหรับ Dart และ Flutter พร้อมอินเตอร์เซพเตอร์และทรานสฟอร์มเมอร์
  • อินเตอร์เซพเตอร์ — กลไกการสกัดกั้นคำขอ การตอบสนอง และข้อผิดพลาดสำหรับการบันทึกและการอนุญาต
  • FormData — รองรับ multipart/form-data ในตัวสำหรับการอัปโหลดไฟล์
  • การยกเลิกคำขอ — CancelToken อนุญาตให้ขัดจังหวะคำขอที่กำลังทำงานได้ทุกเมื่อ
  • ทรานสฟอร์มเมอร์ — การแปลงข้อมูลแบบกำหนดเองก่อนส่งและหลังจากรับ

Dio คืออะไร?

Dio คือไลบรารี HTTP client ที่ทรงพลังสำหรับภาษา Dart ซึ่งใช้กันอย่างแพร่หลายที่สุดในแอปพลิเคชัน Flutter Dio มี API ที่หลากหลายพร้อมรองรับอินเตอร์เซพเตอร์ การกำหนดค่าส่วนกลาง ทรานสฟอร์มเมอร์ FormData การอัปโหลดไฟล์ และการจัดการหมดเวลาที่ยืดหยุ่น ทำให้เป็นตัวเลือกหลักสำหรับการเชื่อมต่อเครือข่ายในชุมชน Flutter

ไลบรารีนี้สร้างขึ้นโดย Wenda Wang ในปี 2018 เพื่อเป็นทางเลือกแทน HttpClient ในตัวของ dart:io ซึ่งขาดคุณสมบัติที่ทันสมัยมากมาย: การกำหนดค่าแบบครบวงจรสำหรับคำขอทั้งหมด อินเตอร์เซพเตอร์ และการทำให้เป็นอนุกรมอัตโนมัติ ภายในปี 2025 Dio แซงหน้าแพ็คเกจ http ของทีม Dart ในด้านความนิยม ครองอันดับหนึ่งในหมู่ HTTP client ในระบบนิเวศ Flutter ตามข้อมูลจาก pub.dev

Dio รองรับอะแดปเตอร์สามตัว: DartNativeAdapter (ค่าเริ่มต้นบน Android, iOS, Desktop), BrowserAdapter (บน Web) และ IOAdapter อะแดปเตอร์จะถูกเลือกโดยอัตโนมัติตามแพลตฟอร์ม Dio ยังมีอินเทอร์เฟซแบบครบวงจรสำหรับทุกแพลตฟอร์ม Flutter — Android, iOS, Web, macOS, Windows และ Linux

Dio ทำงานอย่างไร

สถาปัตยกรรมของ Dio สร้างขึ้นบนห่วงโซ่ตัวจัดการ แต่ละคำขอจะผ่านลำดับของอินเตอร์เซพเตอร์ที่สามารถแก้ไขคำขอ (InterceptorsWrapper.onRequest) การตอบสนอง (onResponse) หรือจัดการข้อผิดพลาด (onError) หลังจากอินเตอร์เซพเตอร์ คำขอจะไปยังทรานสฟอร์มเมอร์ (Transformer) ซึ่งแปลงข้อมูลก่อนส่ง

อินสแตนซ์ของ Dio ถูกกำหนดค่าผ่านออบเจ็กต์ BaseOptions ที่ประกอบด้วย URL พื้นฐาน ส่วนหัวเริ่มต้น การหมดเวลา ประเภทการตอบสนอง (JSON, stream, plain) พารามิเตอร์คำค้นหา และรูปแบบข้อมูล การตั้งค่าเหล่านี้ใช้กับคำขอทั้งหมดแต่สามารถแทนที่ได้ในคำขอเฉพาะ BaseOptions ให้จุดกำหนดค่าเดียวสำหรับทั้งแอปพลิเคชัน ทำให้การเปลี่ยนเอนด์พอยต์หรือการเพิ่มส่วนหัวส่วนกลางทำได้ง่ายขึ้น

แต่ละคำขอใน Dio ส่งคืน Response<T> โดยที่ T คือชนิดข้อมูลหลังจากการประมวลผลของทรานสฟอร์มเมอร์ โดยค่าเริ่มต้น Dio จะแปลงการตอบสนอง JSON เป็น Map<String, dynamic> โดยอัตโนมัติ สำหรับการตอบสนองแบบมีชนิด Dio จะใช้ร่วมกับแพ็คเกจการทำให้เป็นอนุกรม: json_serializable, freezed หรือ built_value Response ประกอบด้วย data, headers, statusCode, requestOptions และข้อมูลเพิ่มเติม

การกำหนดค่าส่วนกลางของ Dio

การกำหนดค่าพื้นฐาน สร้างขึ้นผ่าน Dio(BaseOptions) สามารถตั้งค่า baseUrl สำหรับคำขอทั้งหมด connectTimeout และ receiveTimeout ส่วนหัว content-type และ accept รวมถึง queryParameters พารามิเตอร์ทั้งหมดนี้ใช้กับทุกคำขอ ลดความซ้ำซ้อนของโค้ดและรวมศูนย์การจัดการการตั้งค่าเครือข่าย

Dio รองรับสองโหมดการทำให้เป็นอนุกรม: JSON โดยค่าเริ่มต้น (responseType: ResponseType.json) และสตรีมมิ่ง (ResponseType.stream) ในโหมดสตรีม Response.data ส่งคืน ResponseBody ที่สามารถอ่านเป็นส่วนๆ ได้ ซึ่งสะดวกสำหรับไฟล์ที่มีขนาดใหญ่เมื่อไม่ต้องการโหลดทุกอย่างลงในหน่วยความจำ โหมด plain ส่งคืนสตริงดิบโดยไม่มีการแยกวิเคราะห์ JSON อัตโนมัติ

อินเตอร์เซพเตอร์ของ Dio

อินเตอร์เซพเตอร์ เป็นกลไกหลักของ Dio ในการสกัดกั้นและแก้ไขคำขอ การตอบสนอง และข้อผิดพลาด พวกมันแทนที่ Interceptor ของ OkHttp และปลั๊กอินของ Ktor อย่างสมบูรณ์ แต่ด้วย API เฉพาะของ Dart และการรองรับอะซิงโครนัสผ่าน Future สามารถเพิ่มอินเตอร์เซพเตอร์ได้ทั้งในการกำหนดค่าส่วนกลางของ Dio และสำหรับคำขอแต่ละรายการ

เมธอดอินเตอร์เซพเตอร์วัตถุประสงค์ตัวอย่างการใช้งาน
onRequestแก้ไขคำขอก่อนส่งเพิ่มโทเค็นการอนุญาต
onResponseจัดการการตอบสนองที่สำเร็จแปลง data เป็นออบเจ็กต์ DTO
onErrorจัดการข้อผิดพลาดของคำขอลองใหม่อัตโนมัติเมื่อ 503

LogInterceptor

LogInterceptor ในตัวจะบันทึกทุกคำขอ: เมธอด, URL, ส่วนหัว, เนื้อหา และเวลาดำเนินการ มีสองโหมด: กระชับ (หนึ่งบรรทัดต่อคำขอ) และเต็ม (ข้อมูลครบถ้วนพร้อมเนื้อหา) LogInterceptor มีประโยชน์อย่างยิ่งในระหว่างการพัฒนา แต่แนะนำให้ปิดใช้งานในบิลด์ที่เผยแพร่ผ่านการนำเข้าแบบมีเงื่อนไขหรือแฟลกส่วนกลาง

อินเตอร์เซพเตอร์แบบกำหนดเองสร้างขึ้นผ่านคลาส InterceptorsWrapper สามารถแทนที่หนึ่ง สอง หรือทั้งสามเมธอด (onRequest, onResponse, onError) Dio ดำเนินการอินเตอร์เซพเตอร์ตามลำดับที่เพิ่มในรายการอินเตอร์เซพเตอร์อย่างเคร่งครัด หากอินเตอร์เซพเตอร์ไม่เรียก handler.next() ห่วงโซ่จะหยุดชะงักและการตอบสนองหรือข้อผิดพลาดจะไม่ถึงแอปพลิเคชัน

สำหรับการพิสูจน์ตัวตนใน Dio จะใช้อินเตอร์เซพเตอร์ที่เพิ่มโทเค็น Bearer ในส่วนหัว Authorization หากเซิร์ฟเวอร์ส่งคืน 401 อินเตอร์เซพเตอร์ใน onError จะพยายามรีเฟรชโทเค็นผ่านคำขอรีเฟรชและทำซ้ำคำขอเดิมด้วยโทเค็นใหม่ รูปแบบนี้เรียกว่า ตัวรีเฟรชโทเค็น และถูกนำไปใช้ผ่าน DioException โดยตรวจสอบ response?.statusCode == 401

Dio รองรับตรรกะการลองใหม่ในตัวผ่านแพ็คเกจ dio_smart_retry หรือ RetryInterceptor แบบกำหนดเอง การลองใหม่สำคัญสำหรับแอปพลิเคชันมือถือ: เมื่อการเชื่อมต่อขาดหายไป 2-3 วินาที Dio จะโยน DioException ด้วยชนิด connectionTimeout หรือ connectionError RetryInterceptor จับข้อยกเว้นนี้และลองใหม่สูงสุด 3 ครั้งด้วยหน่วงเวลาแบบเอกซ์โปเนนเชียล (1วินาที, 2วินาที, 4วินาที) ซึ่งช่วยเพิ่มความน่าเชื่อถือของแอปพลิเคชันในสภาพเครือข่ายที่ไม่เสถียร

ตัวอย่างโค้ด Dio ใน Dart

มาดูคำขอ GET พื้นฐานผ่าน Dio กัน สร้างอินสแตนซ์ด้วย BaseOptions กำหนด URL พื้นฐานและการหมดเวลา คำขอถูกดำเนินการผ่านเมธอด get() ที่ส่งคืน Response พร้อมข้อมูลในรูปแบบ Map

dart
final dio = Dio(BaseOptions(
    baseUrl: 'https://api.github.com',
    connectTimeout: Duration(seconds: 15),
    receiveTimeout: Duration(seconds: 15),
    headers: {
        'Accept': 'application/vnd.github.v3+json',
    },
))

final response = await dio.get('/users/octocat')
print(response.data['เข้าสู่ระบบ'])

สำหรับคำขอ POST พร้อมเนื้อหา JSON จะส่งออบเจ็กต์ Map หรือ DTO แบบกำหนดเอง Dio จะทำให้ Map เป็นอนุกรมเป็น JSON โดยอัตโนมัติผ่าน jsonEncode สำหรับ DTO แบบมีชนิด จะใช้ตัวเลือก queryParameters ฟิลด์ data หรือ Transformer แบบกำหนดเอง

dart
final data = {
    'name': 'my-project',
    'description': 'Created via Dio',
    'private': false,
}

final response = await dio.post(
    '/user/repos',
    data: data,
    options: Options(
        contentType: ContentType.json.value,
    ),
)

print(response.data['ไอดี'])

การเพิ่มอินเตอร์เซพเตอร์การอนุญาต

อินเตอร์เซพเตอร์ แบบกำหนดเองจะเพิ่มโทเค็น Bearer ให้กับทุกคำขอ เมธอด onRequest จะทำงานก่อนส่ง แก้ไขส่วนหัว เมื่อการตอบสนอง 401 อินเตอร์เซพเตอร์สามารถรีเฟรชโทเค็นและลองทำคำขออีกครั้งผ่านเมธอด dio.fetch(requestOptions)

dart
class AuthInterceptor extends InterceptorsWrapper {
    final String token

    AuthInterceptor(this.token)

    @override
    void onRequest(
        RequestOptions options,
        RequestInterceptorHandler handler,
    ) {
        options.headers['Authorization'] = 'Bearer $token'
        handler.next(options)
    }
}

dio.interceptors.add(AuthInterceptor('ghp_abc123'))

การอัปโหลดและดาวน์โหลดไฟล์ผ่าน Dio

Dio ทำให้ง่ายขึ้น การอัปโหลดไฟล์ผ่าน FormData ในการส่งไฟล์ จะสร้าง MultipartFile จาก File, Bytes หรือ AssetBundle FormData จะตั้งค่าส่วนหัว multipart/form-data โดยอัตโนมัติพร้อมขอบเขตและการเข้ารหัสที่ถูกต้อง Dio รองรับความคืบหน้าการอัปโหลดผ่าน onSendProgress

สำหรับการดาวน์โหลดไฟล์ จะใช้เมธอด download() ซึ่งบันทึกสตรีมข้อมูลลงในไฟล์โดยตรง Dio รองรับการดาวน์โหลดต่อหลังจากถูกขัดจังหวะผ่านส่วนหัว Range ซึ่งมีประโยชน์โดยเฉพาะสำหรับไฟล์ขนาดใหญ่ ความคืบหน้าการดาวน์โหลด ถูกติดตามผ่าน onReceiveProgress ทำให้สามารถแสดงแถบความคืบหน้าในอินเทอร์เฟซผู้ใช้

dart
final formData = FormData.fromMap({
    'file': await MultipartFile.fromFile(
        '/path/to/photo.jpg',
        filename: 'photo.jpg',
    ),
    'description': 'Profile photo',
})

await dio.post(
    '/upload',
    data: formData,
    onSendProgress: (sent, total) {
        final progress = sent / total * 100
        print('อัปโหลด: $progress%')
    },
)

// ดาวน์โหลดไฟล์
await dio.download(
    'https://example.com/file.zip',
    '/storage/emulated/0/Download/file.zip',
    onReceiveProgress: (received, total) {
        print('ดาวน์โหลด: ${received / total * 100}%')
    },
)

ข้อผิดพลาดทั่วไปเมื่อทำงานกับ Dio

การจัดการข้อผิดพลาดที่ไม่ถูกต้อง เป็นปัญหาที่พบบ่อยที่สุด Dio จะโยน DioException (เดิมคือ DioError) สำหรับปัญหาใดๆ: เครือข่ายไม่พร้อมใช้งาน หมดเวลา ข้อผิดพลาด HTTP 4xx/5xx นักพัฒนาหลายคนจับเฉพาะ Exception ทั่วไป ทำให้สูญเสียข้อมูลเกี่ยวกับชนิดข้อผิดพลาดและความสามารถในการจัดการอย่างเฉพาะเจาะจง ใช้ DioException.type เพื่อระบุสาเหตุของความล้มเหลว

การไม่สนใจ CancelToken นำไปสู่การรั่วไหลของคำขอ หากผู้ใช้ออกจากหน้าจอในขณะที่คำขอยังคงทำงานอยู่ Dio จะสิ้นเปลืองทรัพยากรและอาจพยายามอัปเดต State ที่ถูกทำลาย สร้าง CancelToken สำหรับทุกคำขอเสมอและยกเลิกใน dispose() CancelToken สร้าง DioException ด้วยชนิด cancel ซึ่งต้องได้รับการจัดการอย่างถูกต้อง

ขาดตรรกะการลองใหม่ สำหรับความล้มเหลวชั่วคราว บนอุปกรณ์มือถือ เครือข่ายมักไม่พร้อมใช้งานในช่วงสั้นๆ ใช้อินเตอร์เซพเตอร์กับการลองใหม่คำขออัตโนมัติเมื่อหมดเวลาหรือการตอบสนอง 503/502 ใช้ RetryInterceptor จากแพ็คเกจ dio_smart_retry หรือเขียนอินเตอร์เซพเตอร์แบบกำหนดเองด้วยหน่วงเวลาแบบเอกซ์โปเนนเชียลระหว่างการลอง

คำถามที่พบบ่อย

Dio แตกต่างจากแพ็คเกจ http ของ Dart อย่างไร?

Dio มีอินเตอร์เซพเตอร์ การกำหนดค่า BaseOptions ส่วนกลาง FormData ความคืบหน้าการอัปโหลด และ CancelToken แพ็คเกจ http จากทีม Dart มีความเรียบง่าย ไม่มีอินเตอร์เซพเตอร์หรือการกำหนดค่าส่วนกลาง Dio ใช้ในโปรเจกต์ขนาดใหญ่ ในขณะที่ http ใช้สำหรับสคริปต์ง่ายๆ

จะทำให้ JSON เป็นอนุกรมใน Dio ได้อย่างไร?

โดยค่าเริ่มต้น Dio จะแปลง JSON เป็น Map โดยใช้ jsonDecode สำหรับการทำให้เป็นอนุกรมแบบมีชนิด ให้ใช้แพ็คเกจ json_serializable หรือ freezed สร้างอินเตอร์เซพเตอร์แบบกำหนดเองที่แปลง response.data เป็น DTO ผ่าน fromJson() ใน onResponse

จะยกเลิกคำขอใน Dio ได้อย่างไร?

สร้าง CancelToken และส่งต่อไปในตัวเลือกคำขอ การเรียก token.cancel() จะขัดจังหวะคำขอและโยน DioException ด้วยชนิด cancel CancelToken รองรับการยกเลิกหลายคำขอพร้อมกัน ซึ่งสะดวกสำหรับการยกเลิกคำขอทั้งหมดเมื่อออกจากหน้าจอ

Dio ทำงานบนทุกแพลตฟอร์ม Flutter หรือไม่?

ใช่ Dio ทำงานบนทั้งหกแพลตฟอร์ม Flutter: Android, iOS, Web, macOS, Windows และ Linux แต่ละแพลตฟอร์มใช้ HTTP client ที่ปรับเปลี่ยนได้: DartNativeAdapter (แพลตฟอร์มดั้งเดิม) และ BrowserAdapter (Web) API ที่เป็นหนึ่งเดียวสำหรับทุกแพลตฟอร์มเป็นข้อได้เปรียบหลักของ Dio ในโปรเจกต์ Flutter

Dio จัดการคุกกี้อย่างไร?

Dio ไม่จัดการคุกกี้โดยอัตโนมัติ สำหรับการรองรับคุกกี้ ให้ใช้แพ็คเกจ dio_cookie_manager ร่วมกับ cookie_jar CookieManager จะสกัดกั้นส่วนหัว Set-Cookie และ Cookie และบันทึกคุกกี้ใน PersistCookieJar สำหรับการส่งอัตโนมัติในคำขอถัดไปไปยังโดเมนเดียวกัน

สรุป

  • Dio — HTTP client ที่ได้รับความนิยมมากที่สุดใน Flutter พร้อมอินเตอร์เซพเตอร์และทรานสฟอร์มเมอร์
  • อินเตอร์เซพเตอร์ onRequest, onResponse และ onError แก้ไขคำขอและการตอบสนอง
  • FormData และ MultipartFile ทำให้การอัปโหลดไฟล์ไปยังเซิร์ฟเวอร์ง่ายขึ้น
  • CancelToken ยกเลิกคำขออย่างถูกต้องเพื่อป้องกันหน่วยความจำรั่ว
  • BaseOptions รวมศูนย์การกำหนดค่า URL ส่วนหัวและการหมดเวลา
  • DioException มีชนิดข้อผิดพลาดสำหรับการจัดการความล้มเหลวโดยละเอียด
  • ความคืบหน้า onSendProgress และ onReceiveProgress แสดงสถานะการอัปโหลด

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม