Skip to content
On this page

接口请求

安装http库

dart
// 安装依赖
flutter pub add http

// 引入
import 'package:http/http.dart' as http;

使用http.get()方法从JSONPlaceholder上获取到一个样本相册数据。 这个http.get()方法会返回一个包含ResponseFuture

  • Future是Dart用来处理异步操作的一个核心类,它通常代表一个可能的值或者将来或许会用到的错误。
  • http.Response类包含成功的http请求接收到的数据。
dart
Future<http.Response> fetchAlbum() {
  return http.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'));
}

使用http库进行接口请求

dart
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;

Future<dynamic> fetchData() async {
  var url = Uri.parse('https://jsonplaceholder.typicode.com/albums/1');
  final response = await http.get(url);

  if (response.statusCode == 200) {
    final data = json.decode(response.body);
    return data;
  } else {
    throw Exception('Failed to fetch data');
  }
}

void main() async {
  final data = await fetchData();
  print('响应数据');
  print(data);
}

json.encode()方法需要引入dart:convert库。json.encode()方法会将Map类型转换为String类型。 json.decode()方法需要引入dart:convert库。json.decode()方法会将String类型数据解析成Map数据结构。

使用http封装数据模型进行接口请求

dart
// TODO::和上面直接请求接口相比,封装数据模型的好处是什么?难道每次接口请求都需要先封装一个数据模型?

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

Future<Album> fetchAlbum() async {
  final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'));
  if (response.statusCode == 200) {
    return Album.fromJson(jsonDecode(response.body));
  } else {
    throw Exception('Failed to load album');
  }
}

class Album {
  final int userId;
  final int id;
  final String title;

  const Album({
    required this.userId,
    required this.id,
    required this.title,
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      userId: json['userId'],
      id: json['id'],
      title: json['title'],
    );
  }
}

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late Future<Album> futureAlbum;

  @override
  void initState() {
    super.initState();
    futureAlbum = fetchAlbum();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Fetch Data Example'),
        ),
        body: Center(
          child: FutureBuilder<Album>(
            future: futureAlbum,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Text(snapshot.data!.title);
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              }
              // By default, show a loading spinner.
              return const CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }
}

安装dio库

dart
// 安装
flutter pub add dio
// 引入
import 'package:dio/dio.dart';

使用dio进行接口请求

dart
import 'package:dio/dio.dart';

void main() async{
  Dio dio = Dio();
  final response = await dio.get('https://jsonplaceholder.typicode.com/albums/1');
  print(123);
  print(response);
}

自定义请求头和参数传递

dart
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'dart:io';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  Future<dynamic> requestTest() async {
    // 自定义请求头
    Options options = Options(headers: {HttpHeaders.acceptHeader:"accept: application/json"});
    // 传递参数
    Map<String, dynamic> paras = {"wd":"帅气的阿斌"};

    Dio dio = Dio();
    final response = await dio.get(
        'https://jsonplaceholder.typicode.com/albums/1',
        queryParameters: paras,
        options: options
    );
    if (response.statusCode == 200) {
      print(response);
      return response;
    } else {
      throw Exception('Failed to load album');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'test',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('text'),
        ),
        body: Center(
          child: ElevatedButton(
              onPressed: () {
                print("按钮的单击事件");
                requestTest();
              },
              child: const Text("普通按钮")),
        )
      )
    );
  }
}

使用Baseoptions

dart
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'dart:io';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  Future<dynamic> requestTest() async {
    BaseOptions options = BaseOptions(
      method: 'get',
      baseUrl: 'https://jsonplaceholder.typicode.com',
      queryParameters: {
        'name': 'zhangsan',
        'age': 18
      },
      headers: {
        HttpHeaders.acceptHeader: '*'
      }
    );

    Dio netRequest = Dio(options);
    final response = await netRequest.get('/albums/1');

    if (response.statusCode == 200) {
      print(response);
      return response;
    } else {
      throw Exception('Failed to load album');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'test',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('text'),
        ),
        body: Center(
          child: ElevatedButton(
              onPressed: () {
                print("按钮的单击事件");
                requestTest();
              },
              child: const Text("普通按钮")),
        )
      )
    );
  }
}

请求拦截和响应拦截

dart
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'dart:io';

void main() => runApp(const MyApp());

// 请求拦截
class TokenInterceptor extends Interceptor{

  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    print('请求拦截,填充token');
    var token = 'testtiasdfasfsfafafsafaf';
    options.headers["Authorization"] = "Basic $token";
    super.onRequest(options, handler);
  }

  @override
  void onResponse(Response response, ResponseInterceptorHandler handler) {
    print('响应拦截');
    print(response);
    super.onResponse(response, handler);
  }
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  Future<dynamic> requestTest() async {
    BaseOptions options = BaseOptions(
      method: 'get',
      baseUrl: 'https://jsonplaceholder.typicode.com',
      queryParameters: {
        'name': 'zhangsan',
        'age': 18
      },
      headers: {
        HttpHeaders.acceptHeader: '*'
      }
    );

    Dio netRequest = Dio(options);
    netRequest.interceptors.add(TokenInterceptor());
    final response = await netRequest.get('/albums/1');

    if (response.statusCode == 200) {
      return response;
    } else {
      throw Exception('Failed to load album');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'test',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('text'),
        ),
        body: Center(
          child: ElevatedButton(
              onPressed: () {
                print("按钮的单击事件");
                requestTest();
              },
              child: const Text("普通按钮")),
        )
      )
    );
  }
}