أساسيات HTTP وحزمة http
أساسيات HTTP وحزمة http
تتواصل كل تطبيقات Flutter العملية تقريباً مع خادم بعيد: جلب ملفات المستخدمين، تحميل كتالوجات المنتجات، إرسال بيانات النماذج، أو بث التحديثات المباشرة. كل هذا يحدث عبر HTTP (بروتوكول نقل النص التشعبي) — أساس تبادل البيانات على الويب. قبل كتابة أي سطر من كود Dart للشبكة، تحتاج إلى نموذج ذهني راسخ حول كيفية عمل HTTP.
دورة الطلب والاستجابة
كل تفاعل HTTP يتبع نفس النمط: يرسل العميل (تطبيق Flutter) طلباً إلى الخادم، ويرد الخادم بـ استجابة. تحمل كل رسالة جزأين:
- الترويسات (Headers) — بيانات وصفية حول الرسالة (نوع المحتوى، رمز التفويض، توجيهات التخزين المؤقت، الترميزات المقبولة، إلخ)
- الجسم (Body) — البيانات الفعلية (JSON أو HTML أو بيانات ثنائية أو فارغ)
طلب GET نموذجي إلى واجهة برمجة تطبيقات REST يبدو هكذا على مستوى البروتوكول:
طلب HTTP خام والاستجابة (مفاهيمي)
// الطلب (العميل → الخادم)
GET /users/42 HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer eyJhbGci...
// الاستجابة (الخادم → العميل)
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 87
{"id":42,"name":"Edrees","email":"edrees@example.com","role":"admin"}
طرق HTTP
يحدد HTTP عدة طرق طلب (تسمى أيضاً الأفعال) تُوصل النية إلى الخادم:
- GET — استرجاع مورد؛ لا جسم؛ آمن ومتسق
- POST — إنشاء مورد جديد أو إرسال بيانات؛ له جسم؛ غير متسق
- PUT — استبدال مورد بالكامل؛ متسق
- PATCH — تحديث جزئي لمورد
- DELETE — حذف مورد
رموز الحالة
يرد الخادم دائماً بـ رمز حالة مكوّن من ثلاثة أرقام يخبرك ما إذا نجح الطلب ولماذا قد يكون فشل. يجب أن يعرف كل مطور Flutter النطاقات الرئيسية:
- 2xx نجاح —
200 OK،201 Created،204 No Content - 3xx إعادة توجيه —
301 Moved Permanently،304 Not Modified - 4xx خطأ العميل —
400 Bad Request،401 Unauthorized،403 Forbidden،404 Not Found،422 Unprocessable Entity - 5xx خطأ الخادم —
500 Internal Server Error،503 Service Unavailable
"status" أو "error" تعيدها واجهة برمجة التطبيقات الخاصة بك.إضافة حزمة http إلى Flutter
مكتبة Dart القياسية لا تحتوي على عميل HTTP مدمج مناسب لتطبيقات Flutter. الحل الرسمي هو حزمة http، التي يديرها فريق Dart. أضفها إلى مشروعك بأمر واحد:
إضافة الاعتمادية
// الطرفية — شغّل في جذر مشروعك:
flutter pub add http
// هذا يضيف السطر التالي إلى pubspec.yaml:
// dependencies:
// http: ^1.2.1
// ثم استورده في أي ملف Dart:
import 'package:http/http.dart' as http;
الاسم المستعار as http هو اتفاقية المجتمع. يمنع تعارض الأسماء ويجعل كل موقع استدعاء واضحاً — http.get()، http.post()، إلخ.
أذونات الشبكة على Android وiOS
على المنصات المحمولة يفرض نظام التشغيل قواعد أمان الشبكة على مستوى النظام، وليس فقط في الكود:
- Android — أضف
<uses-permission android:name="android.permission.INTERNET" />إلىandroid/app/src/main/AndroidManifest.xml. معظم قوالب Flutter تضمّنه تلقائياً. - iOS — يحجب أمان نقل التطبيق (ATS) بروتوكول HTTP العادي افتراضياً. التزم بـ
https://في الإنتاج؛ للتطوير المحلي فقط يمكنك إضافة استثناء ATS فيios/Runner/Info.plist.
إجراء أول طلب GET
تعيد الدالة http.get() كائناً من نوع Future<http.Response>. استخدم async/await للحفاظ على وضوح الكود. تحقق دائماً من response.statusCode قبل التعامل مع response.body.
أول طلب GET — جلب مستخدم
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<Map<String, dynamic>> fetchUser(int id) async {
final uri = Uri.parse('https://jsonplaceholder.typicode.com/users/$id');
final response = await http.get(
uri,
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer YOUR_TOKEN',
},
);
if (response.statusCode == 200) {
// response.body هو String خام؛ حوّله إلى Map
return jsonDecode(response.body) as Map<String, dynamic>;
} else {
throw Exception(
'فشل في جلب المستخدم. الحالة: ${response.statusCode}',
);
}
}
فهم كائن الاستجابة
يعرض كائن http.Response الذي تعيده كل استدعاء هذه الخصائص الرئيسية:
statusCode— عدد صحيح (مثل200)body— جسم الاستجابة الخام كـStringبترميز UTF-8bodyBytes— الجسم كـUint8List(للبيانات الثنائية)headers—Map<String, String>من ترويسات الاستجابةreasonPhrase— نص حالة يمكن قراءته بشرياً (مثل"OK")
Uri.parse() أو منشئات Uri.https() / Uri.http() بدلاً من تمرير سلاسل نصية خام. تتعامل متغيرات المنشئ تلقائياً مع ترميز URL لمعاملات الاستعلام، مما يمنع أخطاء الترميز الصعبة التصحيح عندما تحتوي القيم على مسافات أو أحرف خاصة.ملخص
في هذا الدرس تعلمت أن HTTP هو بروتوكول طلب/استجابة حيث يرسل العميل فعلاً (GET، POST...) مع ترويسات وجسم اختياري، ويرد الخادم برمز حالة وجسم. أضفت حزمة http عبر flutter pub add http، استوردتها بالاسم المستعار القياسي as http، وكتبت أول طلب GET غير متزامن يتحقق من رمز الحالة ويحلل جسم JSON. في الدرس التالي ستصمم JSON كفئات Dart مكتوبة باستخدام نمط model / fromJson.