Flutter Use Http Package

作者 flutter0ef3972f93e2無授權條款3K 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫2 天前更新

Use the `http` package to execute GET, POST, PUT, or DELETE requests. Use when you need to fetch from or send data to a REST API.

AI 產生的概覽

指導 Flutter 開發者使用 http 套件進行 REST API 請求、JSON 解析和 UI 整合。

功能
此技能提供使用 http 套件實作 Flutter 網路請求的說明,涵蓋設定、權限、請求執行和回應處理。它解釋如何執行 GET、POST、PUT 和 DELETE 請求,驗證狀態碼,將 JSON 反序列化為強型別 Dart 模型,並將解析工作卸載到背景 isolate。它還包含工作流程檢查清單和整合 FutureBuilder 進行 UI 更新的完整程式碼範例。
適用情境
當建置需要從 REST API 取得資料或向 REST API 傳送資料的 Flutter 應用程式時使用此技能。它適合需要關於設定 http 套件、處理平台權限、解析 JSON 回應或將網路呼叫與 Flutter UI 元件整合的指導的開發者。
執行需求
需要 Flutter 開發環境,並將 http 套件新增為相依性。需要針對 Android(Internet 權限)和 macOS(網路用戶端授權)進行平台特定設定。不包含指令碼;此技能僅提供說明和程式碼範例。

Implementing Flutter Networking

Contents

Configuration & Permissions

Configure the environment and platform-specific permissions required for network access.

  1. Add the http package dependency via the terminal:
    bash
    flutter pub add http
  2. Import the package in your Dart files:
    dart
    import 'package:http/http.dart' as http;
  3. Configure Android permissions by adding the Internet permission to android/app/src/main/AndroidManifest.xml:
    xml
    <uses-permission android:name="android.permission.INTERNET" />
  4. Configure macOS entitlements by adding the network client key to both macos/Runner/DebugProfile.entitlements and macos/Runner/Release.entitlements:
    xml
    <key>com.apple.security.network.client</key><true/>

Request Execution & Response Handling

Execute HTTP operations and map responses to strongly typed Dart objects.

  • URIs: Always parse URL strings using Uri.parse('your_url').
  • Headers: Inject authorization and content-type headers via the headers parameter map. Use HttpHeaders.authorizationHeader for auth tokens.
  • Payloads: For POST and PUT requests, encode the body using jsonEncode() from dart:convert.
  • Status Validation: Evaluate response.statusCode. Treat 200 OK (GET/PUT/DELETE) and 201 CREATED (POST) as success.
  • Error Handling: Throw explicit exceptions for non-success status codes. Never return null on failure, as this prevents FutureBuilder from triggering its error state and causes infinite loading indicators.
  • Deserialization: Parse the raw string using jsonDecode(response.body) and map it to a custom Dart object using a factory constructor (e.g., fromJson).

Background Parsing

Offload expensive JSON parsing to a separate Isolate to prevent UI jank (frame drops).

  • Import package:flutter/foundation.dart.
  • Use the compute() function to run the parsing logic in a background isolate.
  • Ensure the parsing function passed to compute() is a top-level function or a static method, as closures or instance methods cannot be passed across isolates.

Workflow: Executing Network Operations

Use the following checklist to implement and validate network operations.

Task Progress:

  • 1. Define the strongly typed Dart model with a fromJson factory constructor.
  • 2. Implement the network request method returning a Future<Model>.
  • 3. Apply conditional logic based on the operation type:
    • If fetching data (GET): Append query parameters to the URI.
    • If mutating data (POST/PUT): Set 'Content-Type': 'application/json; charset=UTF-8' and attach the jsonEncode body.
    • If deleting data (DELETE): Return an empty model instance on success (200 OK).
  • 4. Validate the statusCode and throw an Exception on failure.
  • 5. Integrate the Future into the UI using FutureBuilder.
  • 6. Handle snapshot.hasData, snapshot.hasError, and default to a CircularProgressIndicator.
  • 7. Feedback Loop: Run the app -> trigger the network request -> review console for unhandled exceptions -> fix parsing or permission errors.

Examples

High-Fidelity Implementation: Fetching and Parsing in the Background

dart
import 'dart:async';import 'dart:convert';import 'dart:io';import 'package:flutter/foundation.dart';import 'package:flutter/material.dart';import 'package:http/http.dart' as http;
// 1. Top-level parsing function for IsolateList<Photo> parsePhotos(String responseBody) {  final parsed = (jsonDecode(responseBody) as List<Object?>)      .cast<Map<String, Object?>>();  return parsed.map<Photo>(Photo.fromJson).toList();}
// 2. Network execution with background parsingFuture<List<Photo>> fetchPhotos() async {  final response = await http.get(    Uri.parse('https://jsonplaceholder.typicode.com/photos'),    headers: {      HttpHeaders.authorizationHeader: 'Bearer your_token_here',      HttpHeaders.acceptHeader: 'application/json',    },  );
  if (response.statusCode == 200) {    // Offload heavy parsing to a background isolate    return compute(parsePhotos, response.body);  } else {    throw Exception('Failed to load photos. Status: ${response.statusCode}');  }}
// 3. Strongly typed modelclass Photo {  final int id;  final String title;  final String thumbnailUrl;
  const Photo({    required this.id,    required this.title,    required this.thumbnailUrl,  });
  factory Photo.fromJson(Map<String, dynamic> json) {    return Photo(      id: json['id'] as int,      title: json['title'] as String,      thumbnailUrl: json['thumbnailUrl'] as String,    );  }}
// 4. UI Integrationclass PhotoGallery extends StatefulWidget {  const PhotoGallery({super.key});
  @override  State<PhotoGallery> createState() => _PhotoGalleryState();}
class _PhotoGalleryState extends State<PhotoGallery> {  late Future<List<Photo>> _futurePhotos;
  @override  void initState() {    super.initState();    // Initialize Future once to prevent re-fetching on rebuilds    _futurePhotos = fetchPhotos();  }
  @override  Widget build(BuildContext context) {    return FutureBuilder<List<Photo>>(      future: _futurePhotos,      builder: (context, snapshot) {        if (snapshot.hasData) {          final photos = snapshot.data!;          return ListView.builder(            itemCount: photos.length,            itemBuilder: (context, index) => ListTile(              leading: Image.network(photos[index].thumbnailUrl),              title: Text(photos[index].title),            ),          );        } else if (snapshot.hasError) {          return Center(child: Text('Error: ${snapshot.error}'));        }                // Default loading state        return const Center(child: CircularProgressIndicator());      },    );  }}

來源與署名

來源:flutter/agent-plugins位於skills/flutter-use-http-package提交0ef3972

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架