@@ -15,10 +15,10 @@ dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截
15
15
16
16
``` yaml
17
17
dependencies :
18
- dio : ^4.0.0-beta7
18
+ dio : ^4.0.0-prev1
19
19
` ` `
20
20
21
- > 4.0 changelog 待补充
21
+ > 如果你是dio 3.x 用户,想了解4.0的变更,请参考 [4.x更新列表](./migration_to_4.x.md)!
22
22
23
23
## 一个极简的示例
24
24
@@ -336,27 +336,30 @@ print(response.statusCode);
336
336
337
337
## 拦截器
338
338
339
- 每个 Dio 实例都可以添加任意多个拦截器,他们组成一个队列,拦截器队列的执行顺序是FIFO。通过拦截器你可以在请求之前或响应之后 (但还没有被 ` then ` 或 ` catchError ` 处理)做一些统一的预处理操作。
339
+ 每个 Dio 实例都可以添加任意多个拦截器,他们组成一个队列,拦截器队列的执行顺序是FIFO。通过拦截器你可以在请求之前、响应之后和发生异常时 (但还没有被 ` then ` 或 ` catchError ` 处理)做一些统一的预处理操作。
340
340
341
341
``` dart
342
-
343
342
dio.interceptors.add(InterceptorsWrapper(
344
- onRequest:(RequestOptions options) async {
345
- // 在请求被发送之前做一些事情
346
- return options; //continue
347
- // 如果你想完成请求并返回一些自定义数据,可以返回一个`Response`对象或返回 `dio.resolve(data )`。
348
- // 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义数据data .
343
+ onRequest:(options, handler) {
344
+ // Do something before request is sent
345
+ return hanlder.next( options) ; //continue
346
+ // 如果你想完成请求并返回一些自定义数据,可以返回一个`Response`,如 `dio.resolve(response )`。
347
+ // 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response .
349
348
//
350
- // 如果你想终止请求并触发一个错误,你可以返回一个`DioError`对象,或返回 `dio.reject(errMsg )`,
349
+ // 如果你想终止请求并触发一个错误,你可以返回一个`DioError`对象,如 `dio.reject(error )`,
351
350
// 这样请求将被中止并触发异常,上层catchError会被调用。
352
351
},
353
- onResponse:(Response response) async {
354
- // 在返回响应数据之前做一些预处理
355
- return response; // continue
352
+ onResponse:(response,handler) {
353
+ // Do something with response data
354
+ return handler.next(response); // continue
355
+ // 如果你想终止请求并触发一个错误,你可以返回一个`DioError`对象,如`dio.reject(error)`,
356
+ // 这样请求将被中止并触发异常,上层catchError会被调用。
356
357
},
357
- onError: (DioError e) async {
358
- // 当请求失败时做一些预处理
359
- return e;//continue
358
+ onError: (DioError e, handler) {
359
+ // Do something with response error
360
+ return handler.next(e);//continue
361
+ // 如果你想完成请求并返回一些自定义数据,可以返回一个`Response`,如`dio.resolve(response)`。
362
+ // 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response.
360
363
}
361
364
));
362
365
```
@@ -365,21 +368,21 @@ dio.interceptors.add(InterceptorsWrapper(
365
368
366
369
``` dart
367
370
import 'package:dio/dio.dart';
368
- class CustomInterceptors extends InterceptorsWrapper {
371
+ class CustomInterceptors extends Interceptor {
369
372
@override
370
- Future onRequest(RequestOptions options) {
371
- print('REQUEST[${options? .method}] => PATH: ${options? .path}');
372
- return super.onRequest(options);
373
+ void onRequest(RequestOptions options, RequestInterceptorHandler handler ) {
374
+ print('REQUEST[${options.method}] => PATH: ${options.path}');
375
+ return super.onRequest(options, handler );
373
376
}
374
377
@override
375
- Future onResponse(Response response) {
376
- print('RESPONSE[${response? .statusCode}] => PATH: ${response? .request?.path}');
377
- return super.onResponse(response);
378
+ Future onResponse(Response response, ResponseInterceptorHandler handler ) {
379
+ print('RESPONSE[${response.statusCode}] => PATH: ${response.request?.path}');
380
+ return super.onResponse(response, handler );
378
381
}
379
382
@override
380
- Future onError(DioError err) {
381
- print('ERROR[${err? .response?.statusCode}] => PATH: ${err? .request? .path}');
382
- return super.onError(err);
383
+ Future onError(DioError err, ErrorInterceptorHandler handler ) {
384
+ print('ERROR[${err.response?.statusCode}] => PATH: ${err.request.path}');
385
+ return super.onError(err, handler );
383
386
}
384
387
}
385
388
```
@@ -390,30 +393,14 @@ class CustomInterceptors extends InterceptorsWrapper {
390
393
391
394
``` dart
392
395
dio.interceptors.add(InterceptorsWrapper(
393
- onRequest:(RequestOptions options) {
394
- return dio .resolve('fake data')
396
+ onRequest:(options, handler ) {
397
+ return handler .resolve(Response(requestOptions:options,data: 'fake data'));
395
398
},
396
399
));
397
400
Response response = await dio.get('/test');
398
401
print(response.data);//'fake data'
399
402
```
400
403
401
- ### 拦截器中支持异步任务
402
-
403
- 拦截器中不仅支持同步任务,而且也支持异步任务, 下面是在请求拦截器中发起异步任务的一个实例:
404
-
405
- ``` dart
406
- dio.interceptors.add(InterceptorsWrapper(
407
- onRequest:(Options options) async{
408
- //...If no token, request token firstly.
409
- Response response = await dio.get("/token");
410
- //Set the token to headers
411
- options.headers["token"] = response.data["data"]["token"];
412
- return options; //continue
413
- }
414
- ));
415
- ```
416
-
417
404
### Lock/unlock 拦截器
418
405
419
406
你可以通过调用拦截器的 ` lock() ` /` unlock ` 方法来锁定/解锁拦截器。一旦请求/响应拦截器被锁定,接下来的请求/响应将会在进入请求/响应拦截器之前排队等待,直到解锁后,这些入队的请求才会继续执行(进入拦截器)。这在一些需要串行化请求/响应的场景中非常实用,后面我们将给出一个示例。
@@ -422,16 +409,18 @@ dio.interceptors.add(InterceptorsWrapper(
422
409
tokenDio = Dio(); //Create a new instance to request the token.
423
410
tokenDio.options = dio.options.copyWith();
424
411
dio.interceptors.add(InterceptorsWrapper(
425
- onRequest:(Options options) async {
412
+ onRequest:(Options options, handler) {
426
413
// If no token, request token firstly and lock this interceptor
427
414
// to prevent other request enter this interceptor.
428
415
dio.interceptors.requestLock.lock();
429
416
// We use a new Dio(to avoid dead lock) instance to request token.
430
- Response response = await tokenDio.get('/token');
431
- //Set the token to headers
432
- options.headers['token'] = response.data['data']['token'];
433
- dio.interceptors.requestLock.unlock();
434
- return options; //continue
417
+ tokenDio.get('/token').then((response){
418
+ //Set the token to headers
419
+ options.headers['token'] = response.data['data']['token'];
420
+ handler.next(options); //continue
421
+ }).catchError((error, stackTrace) {
422
+ handler.reject(error, true);
423
+ }).whenComplete(() => dio.interceptors.requestLock.unlock());
435
424
}
436
425
));
437
426
```
@@ -456,21 +445,23 @@ dio.interceptors.add(InterceptorsWrapper(
456
445
457
446
``` dart
458
447
dio.interceptors.add(InterceptorsWrapper(
459
- onRequest: (Options options) async {
448
+ onRequest: (Options options, handler ) async {
460
449
print('send request:path:${options.path},baseURL:${options.baseUrl}');
461
450
if (csrfToken == null) {
462
451
print('no token,request token firstly...');
463
452
//lock the dio.
464
453
dio.lock();
465
- return tokenDio.get('/token').then((d) {
454
+ tokenDio.get('/token').then((d) {
466
455
options.headers['csrfToken'] = csrfToken = d.data['data']['token'];
467
456
print('request token succeed, value: ' + d.data['data']['token']);
468
457
print( 'continue to perform request:path:${options.path},baseURL:${options.path}');
469
- return options;
470
- }).whenComplete(() => dio.unlock()); // unlock the dio
458
+ handler.next(options);
459
+ }).catchError((error, stackTrace) {
460
+ handler.reject(error, true);
461
+ }) .whenComplete(() => dio.unlock()); // unlock the dio
471
462
} else {
472
463
options.headers['csrfToken'] = csrfToken;
473
- return options;
464
+ handler.next( options) ;
474
465
}
475
466
}
476
467
));
0 commit comments