如何在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",
};