Comments (1)
My solution:
import 'package:dio/dio.dart';
typedef RedirectCallback = bool Function(
Response response, ResponseInterceptorHandler handler);
class RedirectInterceptor extends Interceptor {
final Dio _dio;
RedirectCallback? _redirectCallback;
static const String followRedirects = "followRedirects";
static const String rawUri = "rawUri";
static const String rawRequestOption = "rawRequestOption";
static const String redirectCount = "redirectCount";
RedirectInterceptor(this._dio, {RedirectCallback? onRedirect})
: _redirectCallback = onRedirect;
@override
Future<void> onResponse(
Response response, ResponseInterceptorHandler handler) async {
final isFollowRedirects =
response.requestOptions.extra[followRedirects] as bool? ?? true;
if (!isFollowRedirects) {
handler.next(response);
return;
}
final rawUriValue = response.requestOptions.extra[rawUri] as Uri?;
if (rawUriValue == null) {
response.requestOptions.extra[rawUri] = response.requestOptions.uri;
}
final rawRequestOptionValue = response.requestOptions.extra[rawRequestOption];
if (rawRequestOptionValue == null){
response.requestOptions.extra[rawRequestOption] = response.requestOptions;
}
if (_isRedirect(response.statusCode ?? 0)) {
try {
final redirectCountValue =
response.requestOptions.extra[redirectCount] ?? 0;
if (redirectCountValue >= 5) {
handler.next(response);
return;
}
if (_redirectCallback != null &&
!_redirectCallback!.call(response, handler)) {
return;
}
final location = response.headers.value('location');
if (location == null) throw Exception("Redirect location is null");
final requestOptions = response.requestOptions;
final rawUri = requestOptions.uri.toString();
final newUri = Uri.parse(_parseHttpLocation(rawUri, location));
response.requestOptions.extra[redirectCount] = redirectCountValue + 1;
final option = Options(
sendTimeout: requestOptions.sendTimeout,
receiveTimeout: requestOptions.receiveTimeout,
extra: requestOptions.extra,
// headers: requestOptions.headers
// ..removeWhere((key, value) {
// return key.toLowerCase() == "cookie" || key.toLowerCase() == 'content-length';
// }),
responseType: requestOptions.responseType,
validateStatus: requestOptions.validateStatus,
receiveDataWhenStatusError: requestOptions.receiveDataWhenStatusError,
followRedirects: requestOptions.followRedirects,
maxRedirects: requestOptions.maxRedirects,
persistentConnection: requestOptions.persistentConnection,
requestEncoder: requestOptions.requestEncoder,
responseDecoder: requestOptions.responseDecoder,
listFormat: requestOptions.listFormat,
);
final redirectResponse = await _dio.getUri(
newUri,
options: option,
);
return handler.next(redirectResponse);
} on DioException catch (e) {
return handler.reject(e);
}
}
return handler.next(response);
}
bool _isRedirect(int statusCode) {
return statusCode == 301 ||
statusCode == 302 ||
statusCode == 303 ||
statusCode == 307 ||
statusCode == 308;
}
String _parseHttpLocation(final String rawUri, final String location) {
var location1 = location;
String uri;
if (!location1.contains("://")) {
final schemaEndIndex = rawUri.indexOf("://") + 3;
var index = location1.startsWith("/")
? rawUri.indexOf("/", schemaEndIndex)
: rawUri.substring(schemaEndIndex).lastIndexOf("/") + schemaEndIndex;
if (index == -1) index = rawUri.length - 1;
var baseUrl = rawUri.substring(0, index + 1);
if (baseUrl.endsWith("/")) {
baseUrl = baseUrl.substring(0, baseUrl.length - 1);
}
if (location1.startsWith("/")) {
location1 = location1.substring(1);
}
uri = baseUrl + "/" + location1;
} else {
uri = location1;
}
return uri;
}
}
from dio.
Related Issues (20)
- FormData and List of Int not working as expected. HOT 2
- flutter dynamic coockies management HOT 1
- post请求超时无反应 HOT 1
- Error Dio flutter web HOT 1
- upload file send timeout
- Header is out of order HOT 3
- `ResponseType.stream` is not working on web. HOT 1
- [🔔 Dio] sendTimeout cannot be used without a request body to send HOT 2
- `Transformer.isJsonMimeType` throws format exceptions without caught
- onError is not returning any error HOT 3
- Error when uploading image using MultipartFile.fromBytes in version 5.4.3+1 HOT 1
- 为什么dio的fromMap会将MultipartFile自动放入files字段中 HOT 1
- Error: The method 'debugLog' isn't defined for the class 'BrowserHttpClientAdapter'. HOT 1
- Version 5.5.0 brakes the web build HOT 1
- Is it now possible to use DIO / dio_web_adapter with Web/WASM? HOT 41
- Dio 5.5 broke compilation for WASM HOT 6
- ResponseType.stream returns responce all at once on Web HOT 1
- Date header not parsed correctly HOT 1
- set proxy for BrowserHttpClientAdapter HOT 1
- Dio fetch can't catch error HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dio.