Flutter - Handle status code 302 in POST request

19,587

Solution 1

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.

Solution 2

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.

Solution 3

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.

Solution 4

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
     }
Share:
19,587
Dev9977
Author by

Dev9977

Updated on June 05, 2022

Comments

  • Dev9977
    Dev9977 almost 2 years

    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.