如何在Flutter中发出HTTP请求

915 阅读2分钟
原文链接: zhaima.tech

如何在Flutter中发出HTTP请求

发布于2/1/2020 来自:「前端知否」微信公众号

在这篇文章中,我会介绍Dart如何使用http包发出HTTP请求。

我们将使用JSONPlaceholder作为下面我们的API示例的数据提供者。

GET     /posts
GET     /posts/1
GET     /posts/1/comments
GET     /comments?postId=1
GET     /posts?userId=1
POST    /posts
PUT     /posts/1
PATCH   /posts/1
DELETE  /posts/1

起步

在pubspec.yaml中添加http包依赖项。

dependencies:
  http: ^0.12.0+4

导入库:

import 'package:http/http.dart';

GET 请求

_makeGetRequest() async {  

  // 发起 GET 请求
  String url = 'https://jsonplaceholder.typicode.com/posts';
  Response response = await get(url);

  // 响应信息
  int statusCode = response.statusCode;
  Map<String, String> headers = response.headers;
  String contentType = headers['content-type'];
  String json = response.body;  

  // TODO 把json数据转换为对象...

}

现在,在网址中将/posts替换为/posts /1。使用/ posts返回JSON对象数组,而/posts /1返回单个JSON对象,其中1是您要获取的帖子的ID。

您可以使用dart:convert将原始JSON字符串转换为对象。

POST请求

POST请求用于创建新资源。

_makePostRequest() async {  
  // 创建 POST 请求参数
  String url = 'https://jsonplaceholder.typicode.com/posts';
  
  Map<String, String> headers = {"Content-type": "application/json"};
  
  String json = '{"title": "Hello", "body": "body text", "userId": 1}';  

  // 发起 POST 请求
  Response response = await post(url, headers: headers, body: json);  

  // 检查响应结果状态码
  int statusCode = response.statusCode;  

 // API返回新添加的对象数据
  String body = response.body;
  // {
  //   "title": "Hello",
  //   "body": "body text",
  //   "userId": 1,
  //   "id": 101
  // }
}

PUT请求

PUT请求旨在替换或创建资源(如果资源不存在)。

_makePutRequest() async {  
  // 创建 PUT 请求参数
  String url = 'https://jsonplaceholder.typicode.com/posts/1';
  
  Map<String, String> headers = {"Content-type": "application/json"};
  
  String json = '{"title": "Hello", "body": "body text", "userId": 1}';  

  // 发起 PUT 请求
  Response response = await put(url, headers: headers, body: json);  

  // 检查响应结果状态码
  int statusCode = response.statusCode;  

  // API返回更新后的项目
  String body = response.body;
  // {
  //   "title": "Hello",
  //   "body": "body text",
  //   "userId": 1,
  //   "id": 1
  // }
}

PATCH请求

PATCH请求旨在修改现有资源。

_makePatchRequest() async {  

  // 创建 PATCH 请求参数
  String url = 'https://jsonplaceholder.typicode.com/posts/1';
  
  Map<String, String> headers = {"Content-type": "application/json"};
  
  String json = '{"title": "Hello"}';  

  // 发起 PATCH 请求
  Response response = await patch(url, headers: headers, body: json);  

  // 检查响应结果状态码
  int statusCode = response.statusCode;  

  // 只有title更新了
  String body = response.body;
  // {
  //   "userId": 1,
  //   "id": 1
  //   "title": "Hello",
  //   "body": "quia et suscipit\nsuscipit recusandae... (old body text not changed)",
  // }
}

请注意,传入参数中的JSON字符串仅包含标题,而不包括PUT示例中的其他部分。

DELETE请求

DELETE请求当然是用于删除资源的。

_makeDeleteRequest() async {  

  // 帖子1
  String url = 'https://jsonplaceholder.typicode.com/posts/1';  

  // 发起 DELETE 请求
  Response response = await delete(url);  

  // 检查响应结果状态码
  int statusCode = response.statusCode;
}

授权认证

尽管我们上面使用的示例不需要它,但在现实生活中,您需要使用身份验证请求头,尤其是在执行GET请求以外的操作时。您可以将请求头添加到任何请求,尽管通常将基本凭据(用户名和密码)添加到初始POST请求(用来登录),然后将返回的令牌用于后续请求。

基本认证

import 'dart:convert'
import 'dart:io';

final username = 'username';
final password = 'password';
final credentials = '$username:$password';
final stringToBase64 = utf8.fuse(base64);
final encodedCredentials = stringToBase64.encode(credentials);

Map<String, String> headers = {
  HttpHeaders.contentTypeHeader: "application/json", // 或者其他
  HttpHeaders.authorizationHeader: "Basic $encodedCredentials",
};

在OAuth设置中,您可以将客户端ID和密码放在auth请求头中,并将用户名和密码放在正文中。

请注意,我在这里使用了HttpHeaders常量,这需要导入dart:io。随意使用字符串"content-type"和"authorization"。

Bearer (token) 认证

final token = 'WIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpv';

Map<String, String> headers = {
  HttpHeaders.contentTypeHeader: "application/json", // 或者其他
  HttpHeaders.authorizationHeader: "Bearer $token",
};