Skip to content

Commit 6329315

Browse files
committed
1. Support Flutter Web
2. Support Http/2.0
1 parent 3ca5415 commit 6329315

File tree

89 files changed

+3742
-1913
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+3742
-1913
lines changed

.gitignore

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Files and directories created by pub
2-
.dart_tool/
32
.packages
3+
.dart_tool/
44
.pub/
55
.idea/
66
.example/flutter.png
@@ -10,4 +10,23 @@ pubspec.lock
1010

1111
# Directory created by dartdoc
1212
doc/api/
13-
.cookies/
13+
.cookies/
14+
15+
dio/.packages
16+
dio/.dart_tool/
17+
dio/.pub/
18+
dio/.idea/
19+
dio/.exampl
20+
21+
# plugins
22+
plugins/cookie_manager/.packages
23+
plugins/cookie_manager/.dart_tool/
24+
plugins/cookie_manager/.pub/
25+
plugins/cookie_manager/.idea/
26+
plugins/cookie_manager/.exampl
27+
28+
plugins/http2_adapter/.packages
29+
plugins/http2_adapter/.dart_tool/
30+
plugins/http2_adapter/.pub/
31+
plugins/http2_adapter/.idea/
32+
plugins/http2_adapter/.exampl

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
## Change Log:
22

3-
See https://github.com/flutterchina/dio/blob/master/package_src/CHANGELOG.md
3+
See https://github.com/flutterchina/dio/blob/master/dio/CHANGELOG.md

README.md

+44-68
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@ Language: [English](README.md) | [中文简体](README-ZH.md)
44

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

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

1111
### Add dependency
1212

1313
```yaml
1414
dependencies:
15-
dio: 2.1.x #latest version
15+
dio: 2.2.x #latest version
1616
```
17-
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)
17+
> 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.
18+
1819
## Super simple to use
1920
2021
```dart
@@ -59,9 +60,11 @@ void getHttp() async {
5960

6061
- [HttpClientAdapter](#httpclientadapter )
6162

63+
- [Http2 support](#http2-support )
64+
6265
- [Features and bugs](#features-and-bugs)
6366

64-
67+
6568

6669
## Examples
6770

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

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

128131
```dart
129-
FormData formData = new FormData.from({
132+
FormData.fromMap({
130133
"name": "wendux",
131134
"age": 25,
132-
"file1": new UploadFileInfo(new File("./upload.txt"), "upload1.txt"),
133-
// upload with bytes (List<int>)
134-
"file2": new UploadFileInfo.fromBytes(
135-
utf8.encode("hello world"), "word.txt"),
136-
// Pass multiple files within an Array
135+
"file": await MultipartFile.fromFile("./text.txt",filename: "upload.txt"),
137136
"files": [
138-
new UploadFileInfo(new File("./example/upload.txt"), "upload.txt"),
139-
new UploadFileInfo(new File("./example/upload.txt"), "upload.txt")
137+
await MultipartFile.fromFile("./text1.txt", filename: "text1.txt"),
138+
await MultipartFile.fromFile("./text2.txt", filename: "text2.txt"),
140139
]
141140
});
141+
response = await dio.post("/info", data: formData);
142142
```
143143

144144
Listening the uploading progress:
@@ -170,6 +170,8 @@ await dio.post(
170170

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

173+
174+
173175
## Dio APIs
174176

175177
### Creating an instance and set default configs.
@@ -257,11 +259,11 @@ The Options class describes the http request information and configuration. Each
257259
/// it will be combined and then resolved with the baseUrl.
258260
String path="";
259261
260-
/// The request Content-Type. The default value is [ContentType.JSON].
262+
/// The request Content-Type. The default value is "application/json; charset=utf-8".
261263
/// If you want to encode request body with "application/x-www-form-urlencoded",
262-
/// you can set `ContentType.parse("application/x-www-form-urlencoded")`, and [Dio]
264+
/// you can set [Headers.formUrlEncodedContentType], and [Dio]
263265
/// will automatically encode the request body.
264-
ContentType contentType;
266+
String contentType;
265267
266268
/// [responseType] indicates the type of data that the server will respond with
267269
/// options which defined in [ResponseType] are `JSON`, `STREAM`, `PLAIN`.
@@ -282,9 +284,10 @@ The Options class describes the http request information and configuration. Each
282284
283285
/// Custom field that you can retrieve it later in [Interceptor]、[Transformer] and the [Response] object.
284286
Map<String, dynamic> extra;
287+
288+
/// Common query parameters
289+
Map<String, dynamic /*String|Iterable<String>*/ > queryParameters;
285290
286-
/// Custom Cookies
287-
Iterable<Cookie> cookies;
288291
}
289292
```
290293

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

332335
```dart
333336
dio.interceptors.add(InterceptorsWrapper(
334-
onRequest:(RequestOptions options){
337+
onRequest:(RequestOptions options) async {
335338
// Do something before request is sent
336339
return options; //continue
337340
// If you want to resolve the request with some custom data,
338341
// you can return a `Response` object or return `dio.resolve(data)`.
339342
// If you want to reject the request with a error message,
340343
// you can return a `DioError` object or return `dio.reject(errMsg)`
341344
},
342-
onResponse:(Response response) {
345+
onResponse:(Response response) async {
343346
// Do something with response data
344347
return response; // continue
345348
},
346-
onError: (DioError e) {
349+
onError: (DioError e) async {
347350
// Do something with response error
348351
return e;//continue
349352
}
@@ -357,30 +360,14 @@ In all interceptors, you can interfere with their execution flow. If you want to
357360

358361
```dart
359362
dio.interceptors.add(InterceptorsWrapper(
360-
onRequest:(RequestOptions options){
363+
onRequest:(RequestOptions options) {
361364
return dio.resolve("fake data")
362365
},
363366
));
364367
Response response = await dio.get("/test");
365368
print(response.data);//"fake data"
366369
```
367370

368-
### Supports Async tasks in Interceptors
369-
370-
Interceptors not only support synchronous tasks, but also supports asynchronous tasks, for example:
371-
372-
```dart
373-
dio.interceptors.add(InterceptorsWrapper(
374-
onRequest:(Options options) async{
375-
//...If no token, request token firstly.
376-
Response response = await dio.get("/token");
377-
//Set the token to headers
378-
options.headers["token"] = response.data["data"]["token"];
379-
return options; //continue
380-
}
381-
));
382-
```
383-
384371
### Lock/unlock the interceptors
385372

386373
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.
@@ -421,7 +408,7 @@ Because of security reasons, we need all the requests to set up a csrfToken in t
421408

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

455-
### Cookie Manager
456-
457-
CookieManager Interceptor can help us manage the request/response cookies automaticly. CookieManager depends on `cookieJar` package :
458-
459-
> The dio cookie manage API is based on the withdrawn [cookie_jar](https://github.com/flutterchina/cookie_jar).
460-
461-
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:
462-
463-
```dart
464-
var dio = new Dio();
465-
dio.interceptors.add(CookieManager(CookieJar()))
466-
```
467-
468-
`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.
469-
470-
> 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
442+
### Custom Interceptor
471443

472-
More details about [cookie_jar](https://github.com/flutterchina/cookie_jar) see : https://github.com/flutterchina/cookie_jar .
444+
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).
473445

474-
### Custom Interceptor
446+
## Cookie Manager
475447

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

478450
## Handling Errors
479451

@@ -514,9 +486,6 @@ try {
514486
/// The original error/exception object; It's usually not null when `type`
515487
/// is DioErrorType.DEFAULT
516488
dynamic error;
517-
518-
/// Error stacktrace info
519-
StackTrace stackTrace;
520489
}
521490
```
522491

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

551520
```dart
552521
//Instance level
553-
dio.options.contentType=ContentType.parse("application/x-www-form-urlencoded");
522+
dio.options.contentType= Headers.formUrlEncodedContentType;
554523
//or works once
555-
dio.post("/info",data:{"id":5}, options: new Options(contentType:ContentType.parse("application/x-www-form-urlencoded")));
524+
dio.post("/info", data:{"id":5},
525+
options: Options(contentType:Headers.formUrlEncodedContentType ));
556526
```
557527

558-
There is an example [here](https://github.com/flutterchina/dio/blob/6de8289ea71b0b7803654caaa2e9d3d47a588ab7/example/options.dart#L41).
559-
560528
## Sending FormData
561529

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

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

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

627596
```dart
597+
import 'package:dio/dio.dart';
598+
import 'package:dio/adapter.dart';
599+
...
628600
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
629601
// config the http client
630602
client.findProxy = (uri) {
@@ -668,12 +640,16 @@ Another way is creating a `SecurityContext` when create the `HttpClient`:
668640

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

643+
## Http2 support
644+
645+
[dio_http2_adapter](https://github.com/flutterchina/dio/tree/master/plugins/http2_adapter) package is a Dio HttpClientAdapter which support Http/2.0 .
646+
671647
## Cancellation
672648

673649
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.
674650

675651
```dart
676-
CancelToken token = new CancelToken();
652+
CancelToken token = CancelToken();
677653
dio.get(url1, cancelToken: token);
678654
dio.get(url2, cancelToken: token);
679655

package_src/CHANGELOG.md dio/CHANGELOG.md

+30
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,33 @@
1+
# 2.2.0
2+
3+
### New features
4+
5+
- Support Flutter Web.
6+
- Extract [CookieManager](https://github.com/flutterchina/dio/tree/master/plugins/cookie_manager) into a separate package(No need for Flutter Web).
7+
- Provides a [HTTP/2.0 HttpClientAdapter](https://github.com/flutterchina/dio/tree/master/plugins/http2_adapter).
8+
9+
### Change List
10+
11+
- ~~Options.cookies~~
12+
13+
- ~~Options.connectionTimeout~~ ;We should config connection timed out in `BaseOptions`. For keep-alive reasons, not every request requires a separate connection。
14+
15+
- `Options.followRedirects``Options.maxRedirects``Response.redirects` don't make sense in Flutter Web,because redirection can be automatically handled by browsers.
16+
17+
- ~~FormData.from~~`FormData.fromMap` instead.
18+
19+
- ~~``Formdata.asBytes()`~~、~~`Formdata.asBytesAsync()`~~ , `Formdata.readAsBytes()` instead.
20+
21+
- Delete ~~`UploadFileInfo`~~ class, `MultipartFile` instead.
22+
23+
- 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) .
24+
25+
- The type of `Response.headers` changes from `HttpHeaders` to `Headers`, because `HttpHeaders` is in "dart:io" library which is not supported in Flutter Web.
26+
27+
28+
29+
30+
131

232
# 2.1.16
333

package_src/LICENSE dio/LICENSE

File renamed without changes.

0 commit comments

Comments
 (0)