dio 0.0.14

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 77

Language: English | 中文简体

dio

build statud Pub coverage support

A powerful Http client for Dart, which supports Interceptors, Global configuration, FormData, Request Cancellation, File downloading, Timeout etc.

Add dependency

dependencies:
  dio: ^x.x.x  // latest version

Super simple to use

import 'package:dio/dio.dart';
Dio dio = new Dio();
Response response=await dio.get("https://www.google.com/");
print(response.data);

Table of contents

Examples

Performing a GET request:

Response response;
response=await dio.get("/test?id=12&name=wendu")
print(response.data.toString());
// Optionally the request above could also be done as
response=await dio.get("/test",data:{"id":12,"name":"wendu"})
print(response.data.toString());

Performing a POST request:

response=await dio.post("/test",data:{"id":12,"name":"wendu"})

Performing multiple concurrent requests:

response= await Future.wait([dio.post("/info"),dio.get("/token")]);

Downloading a file:

response=await dio.download("https://www.google.com/","./xx.html")

Sending FormData:

FormData formData = new FormData.from({
   "name": "wendux",
   "age": 25,
});
response = await dio.post("/info", data: formData)

Uploading multiple files to server by FormData:

FormData formData = new FormData.from({
   "name": "wendux",
   "age": 25,
   "file1": new UploadFileInfo(new File("./upload.txt"), "upload1.txt")
   "file2": new UploadFileInfo(new File("./upload.txt"), "upload2.txt")
});
response = await dio.post("/info", data: formData)

…you can find all examples code here.

Dio APIs

Creating an instance and set default configs.

You can create an Dio instance by default options or with a optional Options object:

Dio dio = new Dio; // with default Options

// Set default configs
dio.options.baseUrl="https://www.xx.com/api" 
dio.options.connectTimeout = 5000; //5s
dio.options.receiveTimeout=3000;  

// or new Dio with a Options instance.
Options options= new Options(
    baseUrl:"https://www.xx.com/api",
    connectTimeout:5000,
    receiveTimeout:3000
);
Dio dio = new Dio(options);

The core API in Dio instance is :

Future<Response> request(String path, {data, Options options,CancelToken cancelToken})

response=await request("/test", data: {"id":12,"name":"xx"}, new Options(method:"GET"));

Request method aliases

For convenience aliases have been provided for all supported request methods.

Future<Response> get(path, {data, Options options,CancelToken cancelToken})

Future<Response> post(path, {data, Options options,CancelToken cancelToken})

Future<Response> put(path, {data, Options options,CancelToken cancelToken})

Future<Response> delete(path, {data, Options options,CancelToken cancelToken})

Future<Response> head(path, {data, Options options,CancelToken cancelToken})

Future<Response> put(path, {data, Options options,CancelToken cancelToken})

Future<Response> path(path, {data, Options options,CancelToken cancelToken})

Future<Response> download(String urlPath, savePath, {OnDownloadProgress onProgress, data, bool flush: false, Options options,CancelToken cancelToken})

Request Options

These are the available config options for making requests. Requests will default to GET if method is not specified.

{
  /// Http method.
  String method;

  /// Request base url, it can contain sub path, like: "https://www.google.com/api/".
  String baseUrl;

  /// Http request headers.
  Map<String, dynamic> headers;

   /// Timeout in milliseconds for opening  url.
  int connectTimeout;

   ///  Whenever more than [receiveTimeout] (in milliseconds) passes between two events from response stream,
  ///  [Dio] will throw the [DioError] with [DioErrorType.RECEIVE_TIMEOUT].
  ///  Note: This is not the receiving time limitation.
  int receiveTimeout;

  /// Request data, can be any type.
  var data;

  /// If the `path` starts with "http(s)", the `baseURL` will be ignored, otherwise,
  /// it will be combined and then resolved with the baseUrl.
  String path="";

  /// The request Content-Type. The default value is [ContentType.JSON].
  /// If you want to encode request body with "application/x-www-form-urlencoded",
  /// you can set `ContentType.parse("application/x-www-form-urlencoded")`, and [Dio]
  /// will automatically encode the request body.
  ContentType contentType;

  /// [responseType] indicates the type of data that the server will respond with
  /// options which defined in [ResponseType] are `JSON`, `STREAM`, `PLAIN`.
  ///
  /// The default value is `JSON`, dio will parse response string to json object automatically
  /// when the content-type of response is "application/json".
  ///
  /// If you want to receive response data with binary bytes, for example,
  /// downloading a image, use `STREAM`.
  ///
  /// If you want to receive the response data with String, use `PLAIN`.
  ResponseType responseType;

  /// Custom field that you can retrieve it later in [Interceptor]、[TransFormer] and the [Response] object.
  Map<String, dynamic> extra;
}

There is a complete example here.

Response Schema

The response for a request contains the following information.

{
  /// Response body. may have been transformed, please refer to [ResponseType].
  T data;
  /// Response headers.
  HttpHeaders headers;
  /// The corresponding request info.
  Options request;
  /// Http status code.
  int statusCode;
  /// Custom field that you can retrieve it later in `then`.
  Map<String, dynamic> extra;
}

When request is succeed, you will receive the response as follows:

Response response=await dio.get("https://www.google.com");
print(response.data);
print(response.headers);
print(response.request);
print(statusCode);

Interceptors

Each Dio instance has a RequestInterceptor and a ResponseInterceptor, by which you can intercept requests or responses before they are handled by then or catchError.

 dio.interceptor.request.onSend = (Options options){
     // Do something before request is sent
     return options; //continue
     // If you want to resolve the request with some custom data,
     // you can return a `Response` object or return `dio.resolve(data)`.
     // If you want to reject the request with a error message, 
     // you can return a `DioError` object or return `dio.reject(errMsg)`    
 }
 dio.interceptor.response.onSuccess = (Response response) {
     // Do something with response data
     return response; // continue
 };
 dio.interceptor.response.onError = (DioError e){
     // Do something with response error
     return DioError;//continue
 }    

If you may need to remove an interceptor later you can.

dio.interceptor.request.onSend=null;
dio.interceptor.response.onSuccess=null;
dio.interceptor.response.onError=null;

Resolve and reject the request

In all interceptors, you can interfere with thire execution flow. If you want to resolve the request/response with some custom data, you can return a Response object or return dio.resolve(data). If you want to reject the request/response with a error message, you can return a DioError object or return dio.reject(errMsg) .

 dio.interceptor.request.onSend = (Options options){
     return dio.resolve("fake data")    
 }
 Response response= await dio.get("/test");
 print(response.data);//"fake data"

Supports Async tasks in Interceptors

Interceptors not only support synchronous tasks , but also supports asynchronous tasks, for example:

  dio.interceptor.request.onSend = (Options options) async{
     //...If no token, request token firstly.
     Response response = await dio.get("/token");
     //Set the token to headers 
     options.headers["token"] = response.data["data"]["token"];
     return options; //continue   
 }

Lock/unlock the interceptors

you can lock/unlock the interceptors by calling their lock()/unlock method. Once the request/response interceptor is locked, the incoming request/response will be added to a queue before they enter the interceptor, they will not be continued until the interceptor is unlocked.

tokenDio=new Dio(); //Create a new instance to request the token.
tokenDio.options=dio;
dio.interceptor.request.onSend = (Options options) async{
     // If no token, request token firstly and lock this interceptor
     // to prevent other request enter this interceptor.
     dio.interceptor.request.lock(); 
     // We use a new Dio(to avoid dead lock) instance to request token. 
     Response response = await tokenDio.get("/token");
     //Set the token to headers 
     options.headers["token"] = response.data["data"]["token"];
     dio.interceptor.request.unlock() 
     return options; //continue   
 }

aliases

When the request interceptor is locked, the incoming request will pause, this is equivalent to we locked the current dio instance, Therefore, Dio provied the two aliases for the lock/unlock of request interceptors.

dio.lock() == dio.interceptor.request.lock()

dio.unlock() == dio.interceptor.request.unlock()

Example

Because of security reasons, we need all the requests to set up a csrfToken in the header, if csrfToken does not exist, we need to request a csrfToken first, and then perform the network request, because the request csrfToken progress is asynchronous, so we need to execute this async request in request interceptor. the code is as follows:

dio.interceptor.request.onSend = (Options options) {
    print('send request:path:${options.path},baseURL:${options.baseUrl}');
    if (csrfToken == null) {
      print("no token,request token firstly...");
      //lock the dio.
      dio.lock();
      return tokenDio.get("/token").then((d) {
        options.headers["csrfToken"] = csrfToken = d.data['data']['token'];
        print("request token succeed, value: " + d.data['data']['token']);
        print('continue to perform request:path:${options.path},baseURL:${options.path}');
        return options;
      }).whenComplete(() => dio.unlock()); // unlock the dio
    } else {
      options.headers["csrfToken"] = csrfToken;
      return options;
    }
  };

For complete codes click here.

Handling Errors

When a error occurs, Dio will wrap the Error/Exception to a DioError:

  try {
    //404  
    await dio.get("https://wendux.github.io/xsddddd");
   } on DioError catch(e) {
      // The request was made and the server responded with a status code
      // that falls out of the range of 2xx and is also not 304.
      if(e.response) {
        print(e.response.data) 
        print(e.response.headers) 
        print(e.response.request)    
      } else{
        // Something happened in setting up or sending the request that triggered an Error  
        print(e.request)  
        print(e.message)
      }  
  }

DioError scheme

 {
  /// Response info, it may be `null` if the request can't reach to
  /// the http server, for example, occurring a dns error, network is not available.
  Response response;

  /// Error descriptions.
  String message;
  
  DioErrorType type;

  /// Error stacktrace info
  StackTrace stackTrace;
}

DioErrorType

enum DioErrorType {
  /// Default error type, usually occurs before connecting the server.
  DEFAULT,

  /// When opening  url timeout, it occurs.
  CONNECT_TIMEOUT,

  ///  Whenever more than [receiveTimeout] (in milliseconds) passes between two events from response stream,
  ///  [Dio] will throw the [DioError] with [DioErrorType.RECEIVE_TIMEOUT].
  ///
  ///  Note: This is not the receiving time limitation.
  RECEIVE_TIMEOUT,

  /// When the server response, but with a incorrect status, such as 404, 503...
  RESPONSE,

  /// When the request is cancelled, dio will throw a error with this type.
  CANCEL
}

Using application/x-www-form-urlencoded format

By default, Dio serializes request data(except String type) to JSON. To send data in the application/x-www-form-urlencoded format instead, you can :

//Instance level
dio.options.contentType=ContentType.parse("application/x-www-form-urlencoded");
//or works once
dio.post("/info",data:{"id":5}, options: new Options(contentType:ContentType.parse("application/x-www-form-urlencoded")))    

There is a example here.

Sending FormData

You can also send FormData with Dio, which will send data in the multipart/form-data, and it supports upload files.

FormData formData = new FormData.from({
    "name": "wendux",
    "age": 25,
    "file": new UploadFileInfo(new File("./example/upload.txt"), "upload.txt")
});
response = await dio.post("/info", data: formData)

Note: Just the post method suppots FormData.

There is a complete example here.

Transformer

TransFormer allows changes to the request/response data before it is sent/received to/from the server. Dio has already implemented a DefaultTransformer, and as the default TransFormer. If you want to custom the transformation of request/response data, you can provide a TransFormer by your self, and replace the DefaultTransformer by setting the dio.transformer.

The request transformer TransFormer.transformRequest is only applicable for request methods 'PUT', 'POST', and 'PATCH'。but response transformer TransFormer.transformResponse is applicable for all request methods.

Request flow

Although the request/response data can be preprocessed in the interceptor, the main duty of the TransFormer is to encode/decode the request / response data. The reason for separating the TransFormer alone is to decouple the encoding/decoding operation and other preprocessing interceptor logic, and in order not to modify the original request data (if you modify the request data (options.data) in the interceptor, the original request data will be overwritten, but at some time you may need the original request data). The Dio request flow is:

request interceptor >> TransFormer.transformRequest >> make request >> TransFormer.transformResponse >> response interceptor >> the final result

There is example for customing transformer.

Set proxy and HttpClient config

Dio use HttpClient to send http request, so you can config the httpClient to support proxy, for example:

  dio.onHttpClientCreate = (HttpClient client) {
    client.findProxy = (uri) {
      //proxy all request to localhost:8888
      return "PROXY localhost:8888";
    };
  };

There is a complete example here.

Cancellation

You can cancel a request using a cancel token.

CancelToken token = new CancelToken();
dio.get(url, cancelToken: token)
    .catchError((DioError err){
        if (CancelToken.isCancel(err)) {
            print('Request canceled! '+ err.message)
        }else{
            // handle error.
        }
    })
// cancel the requests with "cancelled" message.
token.cancel("cancelled");

Note: you can cancel several requests with the same cancel token.

There is a complete example here.

You can manage the request/response cookies using cookieJar .

The dio cookie manage API is based on the withdrawn cookie_jar.

You can create a CookieJar or PersistCookieJar to manage cookies automatically, and dio use the CookieJar by default, which saves the cookies in RAM. If you want to persists cookies, you can use the PersistCookieJar class, the example codes as follows:

var dio = new Dio();
dio.cookieJar=new PersistCookieJar("./cookies");

PersistCookieJar is a cookie manager which implements the standard cookie policy declared in RFC. PersistCookieJar persists the cookies in files, so if the application exit, the cookies always exist unless call delete explicitly.

More details about cookie_jar see : https://github.com/flutterchina/cookie_jar .

This open source project authorized by https://flutterchina.club , and the license is MIT.

Features and bugs

Please file feature requests and bugs at the issue tracker.

0.0.10

  • Initial version, created by Stagehand

example/dio.dart

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


main() async {
  var dio = new Dio();
  dio.options.baseUrl = "http://www.dtworkroom.com/doris/1/2.0.0/";
  dio.options.connectTimeout = 5000; //5s
  dio.options.receiveTimeout=5000;
  dio.options.headers = {
    'user-agent': 'dio',
    'common-header': 'xx'
  };

  // Add request interceptor
  dio.interceptor.request.onSend = (Options options) async {
    // return ds.resolve(new Response(data:"xxx"));
    // return ds.reject(new DioError(message: "eh"));
    return options;
  };

  Response response = await dio.get("https://www.google.com/");
  print(response.data);

  // Download a file
  response = await dio.download(
      "https://www.google.com/", "./xx.html", onProgress: (received, total) {
    print('$received,$total');
  });

  // Create a FormData
  FormData formData = new FormData.from({
    "name": "wendux",
    "age": 25,
    "file": new UploadFileInfo(new File("./example/upload.txt"), "upload.txt")
  });

  // Send FormData
  response = await dio.post("/test", data: formData);
  print(response);

  response = await dio.post("/test",
    data: {
      "id": 8,
      "info": {
        "name": "wendux",
        "age": 25
      }
    },
    // Send data with "application/x-www-form-urlencoded" format
    options: new Options(
        contentType: ContentType.parse("application/x-www-form-urlencoded")),
  );
  print(response.data);
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  dio: "^0.0.14"

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter packages get

Alternatively, your editor might support pub get or flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


      import 'package:dio/dio.dart';
  
Version Uploaded Documentation Archive
0.0.14 May 23, 2018 Go to the documentation of dio 0.0.14 Download dio 0.0.14 archive
0.0.13 May 18, 2018 Go to the documentation of dio 0.0.13 Download dio 0.0.13 archive
0.0.12 May 14, 2018 Go to the documentation of dio 0.0.12 Download dio 0.0.12 archive
0.0.11 May 7, 2018 Go to the documentation of dio 0.0.11 Download dio 0.0.11 archive
0.0.10 May 7, 2018 Go to the documentation of dio 0.0.10 Download dio 0.0.10 archive
0.0.9 May 4, 2018 Go to the documentation of dio 0.0.9 Download dio 0.0.9 archive
0.0.8 Apr 27, 2018 Go to the documentation of dio 0.0.8 Download dio 0.0.8 archive
0.0.7 Apr 27, 2018 Go to the documentation of dio 0.0.7 Download dio 0.0.7 archive
0.0.6 Apr 26, 2018 Go to the documentation of dio 0.0.6 Download dio 0.0.6 archive
0.0.5 Apr 26, 2018 Go to the documentation of dio 0.0.5 Download dio 0.0.5 archive

All 14 versions...

Analysis

We analyzed this package on May 23, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0-dev.54.0
  • pana: 0.11.1

Scores

Popularity:
Describes how popular the package is relative to other packages. [more]
55 / 100
Health:
Code health derived from static analysis. [more]
98 / 100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100 / 100
Overall score:
Weighted score of the above. [more]
77
Learn more about scoring.

Platforms

Detected platforms: Flutter, other

Primary library: package:dio/dio.dart with components: io.

Suggestions

  • Fix analysis and formatting issues.

    Analysis or formatting checks reported 17 hints.

    Run dartfmt to format lib/src/CancelToken.dart.

    Run dartfmt to format lib/src/Dio.dart.

    Similar analysis of the following files failed:

    • lib/src/DioError.dart (hint)
    • lib/src/FormData.dart (hint)
    • lib/src/Interceptor.dart (hint)
    • lib/src/Options.dart (hint)
    • lib/src/Response.dart (hint)
    • lib/src/TransFormer.dart (hint)
    • lib/src/UploadFileInfo.dart (hint)
  • Package is pre-v1 release.

    While there is nothing inherently wrong with versions of 0.*.*, it usually means that the author is still experimenting with the general direction API.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=1.20.1 <2.0.0
cookie_jar ^0.0.4 0.0.4
Dev dependencies
coverage ^0.9.3
dart_codecov_generator
test ^0.12.0