I also had this problem, I sent a POST api request using dio library and it returned an error (The request returned an invalid status code of 302)
I issued an identical request using Postman, resulting in a successful response with a status code 200. However, when I attempted the same request in Flutter, it produced an error with a returned status code of 302.
In my case the expected response was the html code of a site I'm being redirected to.
Well, let me explain the problem first:
The HTTP 302
error occurs when the requested resource has been
temporarily moved to a new location. Hence, the system automatically
redirects visitors to a new URL that has the resource.
The HTTP redirect starts when the web server hosting the content
returns a 3xx status code and a location header
that holds the new
URL. Once the web browser receives this response, it automatically
loads the new URL instead of displaying the 404 error not found error.
Source: hostinger.com article
Conclusion/data:
- When you receive a
302
error in Flutter using the Dio
package, it means that the server is trying to redirect you to a different site.
- The default behavior of the
Dio
package is to automatically follow the redirect via the followRedirects
property and get the HTML response from the redirected site.
But I think it failed to redirect since the request was a POST
, since
only "GET" and "HEAD" requests in HttpClientRequest will
auto-redirect
as mentioned in dart.dev.
The solution:
- Prevent Dio from proceeding with redirects "automatically".
- Fetch the link of the site you are supposed to be redirected to (instead of returning it directly in response).
- View the website using any webView library.
Solution steps:
- Set the
FollowRedirects
and maxRedirects
options in the Options
Dio request like this, to prevent automatic redirects from continuing.
final response = await dioClient.post(
// some code
options: Options(
followRedirects: false, // default is true, change to false
maxRedirects: 0, // set to 0
),
);
- Set
validateStatus
as follows:
Options(
validateStatus: (status) => status! < 500, // or (=> status != null & status < 500 ? true : false), to avoid null exception
),
It is preferable to set these two previous options only for this request without affecting the rest of the requests.
- Get the URL of the site you are supposed to be redirected to via
response.headers['location']
like this:
String? redirectUrl;
if(response.statusCode == 302){ // check if status code equals 302, then get the redirect url
redirectUrl = '${response.headers['location']}'; // get the redirect URL
}
- View the website using any webView package, like
webview_flutter
.
The full code would be like:
final response = await dioClient.post(
// URI here
data: // data here
options: Options(
followRedirects: false,
maxRedirects: 0,
validateStatus: (status) => status! < 500,
),
);
String? redirectUrl;
if(response.statusCode == 302){ // check if status code equals 302, then get the redirect url
redirectUrl = '${response.headers['location']}';
debugPrint('is redirect: ${response.isRedirect}');
log('redirect location: $redirectUrl');
} else if (response.statusCode == 200){
// some code here
}