Flutter 之网络请求Dio, FormData, 表单网络请求, x-www-form-urlencoded

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter 之网络请求Dio, FormData, 表单网络请求, x-www-form-urlencoded相关的知识,希望对你有一定的参考价值。

参考技术A 网络请求, 先想到的是dart官方维护的 http 库. 由于我们项目组网络请求都采用的表单结构, http 貌似不支持表单格式的网络请求; 后来查看 dio 库, 发现支持 FormData , 完美解决!

官方表单网络请求示例:

比葫芦画瓢, 尝试下

Flutter--网络请求dio封装网络请求框架


dio简介

  • dio库支持文件的上传和下载,Cookie管理、FormData、请求/取消、拦截器等,和Android中的OkHttp库相似

基本用法

import package:dio/dio.dart;

_loadDataGet() async
try
Response response = await Dio().get("https://www.baidu.com");
print(response);
catch (e)
print(e);



_loadDataPost() async
try
Response response = await Dio().post("path", data: );
print(response);
catch (e)
print(e);

Dio单例

var dio = new Dio(BaseOptions(
baseUrl: "url",
connectTimeout: 5000,
receiveTimeout: 10000,

headers:
HttpHeaders.userAgentHeader: "dio",
"api": "1.0.0",
,
contentType: ContentType.json,
responseType: ResponseType.plain
));

Dio拦截器

  • 官方示例
dio.interceptors.add(InterceptorsWrapper(
onRequest:(RequestOptions options) async
// 请求发送前处理
return options; //continue
,
onResponse:(Response response) async
// 在返回响应数据之前做一些预处理
return response; // continue
,
onError: (DioError e) async
// 当请求失败时做一些预处理
return e;//continue

));
  • 注意:
  • 在拦截器做request处理时,可以直接返回options,这个时候会继续处理then方法里的逻辑,如果想要完成请求并返回一些自定义的数据,可以返回一个Response对象或返回dio.resolve(data),可以使得请求终止,上层的then会被调用,then中返回的数据是自定义的数据

封装dio网络请求

  • 首先创建一个单例
class HttpRequest 
static String _baseUrl = Api.BASE_URL;
static HttpRequest instance;

Dio dio;
BaseOptions options; // 基类请求配置,还可以使用Options单次请求配置,RequestOptions实际请求配置对多个域名发起请求

CancelToken cancelToken = CancelToken();

static HttpRequest getInstance()
if (instance == null)
instance = HttpRequest();

return instance;

  • 配置并初始化dio参数
HttpRequest() 
options = BaseOptions(
// 访问url
baseUrl: _baseUrl,
// 连接超时时间
connectTimeout: 5000,
// 响应流收到数据的间隔
receiveTimeout: 15000,
// http请求头
headers: "version": "1.0.0",
// 接收响应数据的格式
responseType: ResponseType.plain,
);
dio = Dio(options);

// 在拦截其中加入Cookie管理器
dio.interceptors.add(CookieManager(CookieJar()));

//添加拦截器
dio.interceptors.add(InterceptorsWrapper(onRequest: (RequestOptions options)
// Do something before request is sent
return options; //continue
, onResponse: (Response response)
// Do something with response data
return response; // continue
, onError: (DioError e)
// Do something with response error
return e; //continue
));
  • 取消请求
// cancelToken可用于多个请求,也可同时取消多个请求
void cancelRequests(CancelToken token)
token.cancel("cancelled");
  • get请求
get(url,
data,
options,
cancelToken,
BuildContext context,
Function successCallBack,
Function errorCallBack) async
Response response;
try
response = await dio.get(url,
queryParameters: data, options: options, cancelToken: cancelToken);
on DioError catch (e)
handlerError(e);

if (response.data != null)
BaseResponse baseResponse =
BaseResponse.fromJson(json.decode(response.data));
if (baseResponse != null)
switch (baseResponse.errorCode)
case 成功状态码:
successCallBack(jsonEncode(baseResponse.data));
break;
case 其他状态码:
errorCallBack(baseResponse.errorCode, baseResponse.errorMessage);

break;
default:
errorCallBack(baseResponse.errorCode, baseResponse.errorMessage);
break;

else
errorCallBack(Constants.NETWORK_JSON_EXCEPTION, "网络数据问题");

else
errorCallBack(Constants.NETWORK_ERROR, "网络出错啦,请稍后重试");

  • 注意:
  • url:请求地址
  • data:请求参数
  • options:请求配置
  • cancelToken:取消标识
  • post请求
post(url,
data,
options,
cancelToken,
BuildContext context,
Function successCallBack,
Function errorCallBack) async
Response response;
try
response = await dio.post(url,
queryParameters: data, options: options, cancelToken: cancelToken);
on DioError catch (e)
handlerError(e);

if (response.data != null)
BaseResponse baseResponse =
BaseResponse.fromJson(json.decode(response.data));
if (baseResponse != null)
switch (baseResponse.errorCode)
case 成功状态码:
successCallBack(jsonEncode(baseResponse.data));
break;
case 其他状态码:
errorCallBack(baseResponse.errorCode, baseResponse.errorMessage);
break;
default:
errorCallBack(baseResponse.errorCode, baseResponse.errorMessage);
break;

else
errorCallBack(Constants.NETWORK_JSON_EXCEPTION, "网络数据问题");

else
errorCallBack(Constants.NETWORK_ERROR, "网络出错啦,请稍后重试");

  • 下载文件
downloadFile(urlPath, savePath) async 
Response response;
try
response = await dio.download(urlPath, savePath,onReceiveProgress: (int count, int total)
//进度
print("$count $total");
);
print(downloadFile success---------$response.data);
on DioError catch (e)
print(downloadFile error---------$e);
handlerError(e);

return response.data;
  • 错误处理
handlerError(DioError e) 
if (e.type == DioErrorType.CONNECT_TIMEOUT)
print("连接超时");
else if (e.type == DioErrorType.SEND_TIMEOUT)
print("请求超时");
else if (e.type == DioErrorType.RECEIVE_TIMEOUT)
print("响应超时");
else if (e.type == DioErrorType.RESPONSE)
print("响应异常");
else if (e.type == DioErrorType.CANCEL)
print("请求取消");
else
print("未知错误");


以上是关于Flutter 之网络请求Dio, FormData, 表单网络请求, x-www-form-urlencoded的主要内容,如果未能解决你的问题,请参考以下文章

Flutter学习日记之Http&Dio网络请求的使用与封装

Flutter--网络请求dio封装网络请求框架

Flutter网络请求Dio库的使用及封装

Flutter从入门到入土网络请求Dio

flutter dio 网络请求问题

技惊四座的Flutter丨网络请求框架 dio