Skip to content

Commit

Permalink
1. Support Flutter Web
Browse files Browse the repository at this point in the history
2. Support Http/2.0
  • Loading branch information
wendux committed Sep 17, 2019
1 parent 3ca5415 commit 6329315
Show file tree
Hide file tree
Showing 89 changed files with 3,742 additions and 1,913 deletions.
23 changes: 21 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Files and directories created by pub
.dart_tool/
.packages
.dart_tool/
.pub/
.idea/
.example/flutter.png
Expand All @@ -10,4 +10,23 @@ pubspec.lock

# Directory created by dartdoc
doc/api/
.cookies/
.cookies/

dio/.packages
dio/.dart_tool/
dio/.pub/
dio/.idea/
dio/.exampl

# plugins
plugins/cookie_manager/.packages
plugins/cookie_manager/.dart_tool/
plugins/cookie_manager/.pub/
plugins/cookie_manager/.idea/
plugins/cookie_manager/.exampl

plugins/http2_adapter/.packages
plugins/http2_adapter/.dart_tool/
plugins/http2_adapter/.pub/
plugins/http2_adapter/.idea/
plugins/http2_adapter/.exampl
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
## Change Log:

See https://github.com/flutterchina/dio/blob/master/package_src/CHANGELOG.md
See https://github.com/flutterchina/dio/blob/master/dio/CHANGELOG.md
112 changes: 44 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ Language: [English](README.md) | [中文简体](README-ZH.md)

[![build status](https://img.shields.io/travis/flutterchina/dio/vm.svg?style=flat-square)](https://travis-ci.org/flutterchina/dio)
[![Pub](https://img.shields.io/pub/v/dio.svg?style=flat-square)](https://pub.dartlang.org/packages/dio)
[![support](https://img.shields.io/badge/platform-flutter%7Cdart%20vm-ff69b4.svg?style=flat-square)](https://github.com/flutterchina/dio)
[![support](https://img.shields.io/badge/platform-flutter%7Cflutter%20web%7Cdart%20vm-ff69b4.svg?style=flat-square)](https://github.com/flutterchina/dio)

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

### Add dependency

```yaml
dependencies:
dio: 2.1.x #latest version
dio: 2.2.x #latest version
```
If you are using 1.x , this doc can help you upgrade to 2.x. [Change log](https://github.com/flutterchina/dio/blob/master/CHANGELOG.md)
> In order to support Flutter Web, v2.2.0 was heavily refactored, so it was not compatible with version 2.1.x. See [here](https://github.com/flutterchina/dio/blob/master/dio/CHANGELOG.md) for a detailed list of updates.
## Super simple to use
```dart
Expand Down Expand Up @@ -59,9 +60,11 @@ void getHttp() async {

- [HttpClientAdapter](#httpclientadapter )

- [Http2 support](#http2-support )

- [Features and bugs](#features-and-bugs)



## Examples

Expand Down Expand Up @@ -116,7 +119,7 @@ print(rs.data); // List<int>
Sending FormData:

```dart
FormData formData = new FormData.from({
FormData formData = new FormData.fromMap({
"name": "wendux",
"age": 25,
});
Expand All @@ -126,19 +129,16 @@ response = await dio.post("/info", data: formData);
Uploading multiple files to server by FormData:

```dart
FormData formData = new FormData.from({
FormData.fromMap({
"name": "wendux",
"age": 25,
"file1": new UploadFileInfo(new File("./upload.txt"), "upload1.txt"),
// upload with bytes (List<int>)
"file2": new UploadFileInfo.fromBytes(
utf8.encode("hello world"), "word.txt"),
// Pass multiple files within an Array
"file": await MultipartFile.fromFile("./text.txt",filename: "upload.txt"),
"files": [
new UploadFileInfo(new File("./example/upload.txt"), "upload.txt"),
new UploadFileInfo(new File("./example/upload.txt"), "upload.txt")
await MultipartFile.fromFile("./text1.txt", filename: "text1.txt"),
await MultipartFile.fromFile("./text2.txt", filename: "text2.txt"),
]
});
response = await dio.post("/info", data: formData);
```

Listening the uploading progress:
Expand Down Expand Up @@ -170,6 +170,8 @@ await dio.post(

…you can find all examples code [here](https://github.com/flutterchina/dio/tree/master/example).



## Dio APIs

### Creating an instance and set default configs.
Expand Down Expand Up @@ -257,11 +259,11 @@ The Options class describes the http request information and configuration. Each
/// it will be combined and then resolved with the baseUrl.
String path="";
/// The request Content-Type. The default value is [ContentType.JSON].
/// The request Content-Type. The default value is "application/json; charset=utf-8".
/// 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]
/// you can set [Headers.formUrlEncodedContentType], and [Dio]
/// will automatically encode the request body.
ContentType contentType;
String contentType;
/// [responseType] indicates the type of data that the server will respond with
/// options which defined in [ResponseType] are `JSON`, `STREAM`, `PLAIN`.
Expand All @@ -282,9 +284,10 @@ The Options class describes the http request information and configuration. Each
/// Custom field that you can retrieve it later in [Interceptor]、[Transformer] and the [Response] object.
Map<String, dynamic> extra;
/// Common query parameters
Map<String, dynamic /*String|Iterable<String>*/ > queryParameters;
/// Custom Cookies
Iterable<Cookie> cookies;
}
```

Expand Down Expand Up @@ -331,19 +334,19 @@ For each dio instance, We can add one or more interceptors, by which we can inte

```dart
dio.interceptors.add(InterceptorsWrapper(
onRequest:(RequestOptions options){
onRequest:(RequestOptions options) async {
// 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)`
},
onResponse:(Response response) {
onResponse:(Response response) async {
// Do something with response data
return response; // continue
},
onError: (DioError e) {
onError: (DioError e) async {
// Do something with response error
return e;//continue
}
Expand All @@ -357,30 +360,14 @@ In all interceptors, you can interfere with their execution flow. If you want to

```dart
dio.interceptors.add(InterceptorsWrapper(
onRequest:(RequestOptions options){
onRequest:(RequestOptions 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:

```dart
dio.interceptors.add(InterceptorsWrapper(
onRequest:(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.
Expand Down Expand Up @@ -421,7 +408,7 @@ Because of security reasons, we need all the requests to set up a csrfToken in t

```dart
dio.interceptors.add(InterceptorsWrapper(
onRequest: (Options options) {
onRequest: (Options options) async {
print('send request:path:${options.path},baseURL:${options.baseUrl}');
if (csrfToken == null) {
print("no token,request token firstly...");
Expand Down Expand Up @@ -452,28 +439,13 @@ You can set `LogInterceptor` to print request/response log automaticlly, for e
dio.interceptors.add(LogInterceptor(responseBody: false)); //开启请求日志
```

### Cookie Manager

CookieManager Interceptor can help us manage the request/response cookies automaticly. CookieManager depends on `cookieJar` package :

> The dio cookie manage API is based on the withdrawn [cookie_jar](https://github.com/flutterchina/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:

```dart
var dio = new Dio();
dio.interceptors.add(CookieManager(CookieJar()))
```

`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.

> Note: In flutter, the path passed to `PersistCookieJar` must be valid(exists in phones and with write access). you can use [path_provider](https://pub.dartlang.org/packages/path_provider) package to get right path
### Custom Interceptor

More details about [cookie_jar](https://github.com/flutterchina/cookie_jar) see : https://github.com/flutterchina/cookie_jar .
You can custom interceptor by extending the `Interceptor` class. There is an example that implementing a simple cache policy: [custom cache interceptor](https://github.com/flutterchina/dio/blob/master/example/custom_cache_interceptor.dart).

### Custom Interceptor
## Cookie Manager

You can custom interceptor by extending the `Interceptor` class. There is an example that implementing a simple cache policy: custom cache interceptor.
[dio_cookie_manager](https://github.com/flutterchina/dio/tree/master/plugins/cookie_manager) package is a cookie manager for Dio.

## Handling Errors

Expand Down Expand Up @@ -514,9 +486,6 @@ try {
/// The original error/exception object; It's usually not null when `type`
/// is DioErrorType.DEFAULT
dynamic error;
/// Error stacktrace info
StackTrace stackTrace;
}
```

Expand Down Expand Up @@ -550,22 +519,21 @@ By default, Dio serializes request data(except String type) to `JSON`. To send d

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

There is an example [here](https://github.com/flutterchina/dio/blob/6de8289ea71b0b7803654caaa2e9d3d47a588ab7/example/options.dart#L41).

## Sending FormData

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

```dart
FormData formData = new FormData.from({
FormData formData = FormData.from({
"name": "wendux",
"age": 25,
"file": new UploadFileInfo(new File("./example/upload.txt"), "upload.txt")
"file": await MultipartFile.fromFile("./text.txt",filename: "upload.txt")
});
response = await dio.post("/info", data: formData);
```
Expand All @@ -583,6 +551,7 @@ There is a complete example [here](https://github.com/flutterchina/dio/blob/mast
If you use dio in flutter development, you'd better to decode json in background with [compute] function.

```dart
// Must be top-level function
_parseAndDecode(String response) {
return jsonDecode(response);
Expand Down Expand Up @@ -625,6 +594,9 @@ dio.httpClientAdapter = new DefaultHttpClientAdapter();
`DefaultHttpClientAdapter` provide a callback to set proxy to `dart:io:HttpClient`, for example:

```dart
import 'package:dio/dio.dart';
import 'package:dio/adapter.dart';
...
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
// config the http client
client.findProxy = (uri) {
Expand Down Expand Up @@ -668,12 +640,16 @@ Another way is creating a `SecurityContext` when create the `HttpClient`:

In this way, the format of certificate must be PEM or PKCS12.

## Http2 support

[dio_http2_adapter](https://github.com/flutterchina/dio/tree/master/plugins/http2_adapter) package is a Dio HttpClientAdapter which support Http/2.0 .

## Cancellation

You can cancel a request using a *cancel token*. One token can be shared with multiple requests. When a token's `cancel` method invoked, all requests with this token will be cancelled.

```dart
CancelToken token = new CancelToken();
CancelToken token = CancelToken();
dio.get(url1, cancelToken: token);
dio.get(url2, cancelToken: token);
Expand Down
30 changes: 30 additions & 0 deletions package_src/CHANGELOG.md → dio/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
# 2.2.0

### New features

- Support Flutter Web.
- Extract [CookieManager](https://github.com/flutterchina/dio/tree/master/plugins/cookie_manager) into a separate package(No need for Flutter Web).
- Provides a [HTTP/2.0 HttpClientAdapter](https://github.com/flutterchina/dio/tree/master/plugins/http2_adapter).

### Change List

- ~~Options.cookies~~

- ~~Options.connectionTimeout~~ ;We should config connection timed out in `BaseOptions`. For keep-alive reasons, not every request requires a separate connection。

- `Options.followRedirects``Options.maxRedirects``Response.redirects` don't make sense in Flutter Web,because redirection can be automatically handled by browsers.

- ~~FormData.from~~`FormData.fromMap` instead.

- ~~``Formdata.asBytes()`~~、~~`Formdata.asBytesAsync()`~~ , `Formdata.readAsBytes()` instead.

- Delete ~~`UploadFileInfo`~~ class, `MultipartFile` instead.

- The return type of Interceptor's callback changes from `FutureOr<dynamic>` to `Future`. The reason is [here](https://dart.dev/guides/language/effective-dart/design#avoid-using-futureort-as-a-return-type) .

- The type of `Response.headers` changes from `HttpHeaders` to `Headers`, because `HttpHeaders` is in "dart:io" library which is not supported in Flutter Web.






# 2.1.16

Expand Down
File renamed without changes.
Loading

0 comments on commit 6329315

Please sign in to comment.