I'm trying to send a post
request in Flutter with DIO
package.
Here is the request:
getSessionId() async {
var csrf = await getCsrftoken();
var dio = new Dio(new Options(
baseUrl: "http://xxxxxxx/accounts/login/",
connectTimeout: 5000,
receiveTimeout: 100000,
// 5s
headers: {
'Cookie': "csrftoken=" + csrf
},
contentType: ContentType.JSON,
// Transform the response data to a String encoded with UTF8.
// The default value is [ResponseType.JSON].
responseType: ResponseType.PLAIN
));
var response;
response = await dio.post("http://xxxxxxx/accounts/login/",
data: {
"username": "xxxxx",
"password": "xxxxx",
"csrfmiddlewaretoken" : csrf
},
options: new Options(
contentType: ContentType.parse("application/x-www-form-urlencoded")),
);
print("StatusCode: ");
print(response.statusCode);
print("Response cookie: "); //THESE ARE NOT PRINTED
print(response.headers);
}
After the request i get:
E/flutter ( 4567): [ERROR:flutter/shell/common/shell.cc(181)] Dart Error: Unhandled exception:
E/flutter ( 4567): DioError [DioErrorType.RESPONSE]: Http status error [302]
E/flutter ( 4567): #0 getSessionId (file:///C:/get_order/lib/main.dart:36:14)
E/flutter ( 4567): <asynchronous suspension>
From this request i only need to get the sessionid
cookie, but the function stop with unhandled exception.
I solved this way:
Add followRedirects: false
and validateStatus: (status) { return status < 500;}
to the request. Like this:
var response = await Dio().post("http://myurl",
data: requestBody,
options: Options(
followRedirects: false,
validateStatus: (status) { return status < 500; }
),
);
This way you can get from the 302
every headers
and other.
i got a similar problem and i solved it with adding header with "Accept":"application/json" . henceforth it will only return json data otherwise it will prompt to redirect with html url.
The Dart HTTP client won't follow redirects for POSTs unless the response code is 303. It follows 302 redirects for GET or HEAD.
You could see if you can stop the server sending the redirect in response to a (presumably) valid login request, and send a 200 instead.
Or you could try sending the login request as a GET by encoding the form fields into the URL, for example:
http://xxxxxxx/accounts/login/?username=xxxx&password=yyyy&csrfmiddlewaretoken=zzzz
You would have to URL encode any special characters in the parameters. Presumably, you'll want to use HTTPS too.
Finally, is the URL meant to end with /
? It might be worth trying /accounts/login
.
Redirections for 302 are made in response to GET or HEAD requests, never for POST. Sometimes server sends 302 in response to POST (that was in my case). In this case Dio throws exception you can catch - remember to check if server status code is 302 or maybe it's another error.
try{
await dio.post( _urlLogin,
data:{...},
options: Options(
contentType: ContentType.parse("application/x-www-form-urlencoded"),
)
);
}on DioError catch(error){
if(error.response.statusCode == 302){
// do your stuff here
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With