How to post x-www-form-urlencoded in Flutter

Mathieu picture Mathieu · May 26, 2020 · Viewed 9.7k times · Source

I am trying to send a POST request to an API to create an account.
The request is working well, it should look like this :

Bulk Edit Mode :
Bulk Edit mode

Key-Value Edit mode :
Key-Value Edit mode

There are also 9 headers that are auto-generated, so I did not show them, but I can take another screen if you need to.

My request looks like this :

import 'dart:convert' as convert ;

import 'package:my_project/requests/utils.dart';
import 'package:http/http.dart' as http;


Future<String>      createUser(String firstName, String name, String mail,
    String password, String confirmPassword, String birthDate,
    String phone) async {
  String              url = BASE_URL + "createUser" ; // Don't worry about BASE_URL, the final url is correct

  Map<String, dynamic>    formMap = {
    "name": name,
    "surname": firstName,
    "mail": mail,
    "password": password,
    "birth": birthDate,
    "phone": phone,
    "confirmPassword": confirmPassword
  } ;

  http.Response    response = await http.post(
    url,
    body: convert.jsonEncode(formMap),
    headers: {
      "Content-Type": "application/x-www-form-urlencoded"
    },
    encoding: convert.Encoding.getByName("utf-8"),
  );
  print("RESPONSE ${response.statusCode} ; BODY = ${response.body}");

  return (response.body) ;

}

Here is my print result :

I/flutter ( 6942): RESPONSE 307 ; BODY =  

As you can see, I am getting a 307 error, and the problem does not come from the server, as it worked with Postman.

Am I sending this form-urlencoded POST request correctly ?

I also tried :

http.Response    response = await http.post(
    url,
    body: "name=$name&surname=$firstName&mail=$mail&password=$password&birth=$birthDate&phone=$phone&confirmPassword=$confirmPassword",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded"
    },
    encoding: convert.Encoding.getByName("utf-8"),
  );

but with the same results. I tried too :

http.Response    response = await http.post(
    url,
    body: formMap,
    headers: {
      "Content-Type": "application/x-www-form-urlencoded"
    },
    encoding: convert.Encoding.getByName("utf-8"),
  );

with same result again.
What am I doing wrong ?

EDIT :

I tried FoggyDay answer, here is my request now :

final client = HttpClient() ;
final request = await client.postUrl(Uri.parse(url));
request.headers.set(HttpHeaders.contentTypeHeader, "application/x-www_form-urlencoded");
request.followRedirects = true ;
request.write(formMap);
final response = await request.close();
print("STATUS CODE = ${response.statusCode}");

However I still have a 307 error. Did I create the right request ?

EDIT 2 :

As asked, I printed location as follow :

final client = HttpClient() ;
final request = await client.postUrl(Uri.parse(url));
request.headers.set(HttpHeaders.contentTypeHeader, "application/x-www_form-urlencoded");
request.followRedirects = true ;
request.write(formMap);
final response = await request.close();
print("STATUS CODE = ${response.statusCode}");
print("Response headers = ${response.headers}");

And I get :

I/flutter ( 7671): STATUS CODE = 307
I/flutter ( 7671): Response headers = location: /app/createUser/
I/flutter ( 7671): date: Tue, 26 May 2020 09:00:29 GMT
I/flutter ( 7671): content-length: 0
I/flutter ( 7671): server: Apache/2.4.41 (Amazon) OpenSSL/1.0.2k-fips

The thing is I am already making a call on /app/createUser... ('/app/' is in BASE_URL)

Answer

Parisa Baastani picture Parisa Baastani · May 24, 2021

For x-www-form-urlencoded parameters, just use this:

  Future<String> login(user, pass) async {
   final response = await http.post(
    Uri.parse('https:youraddress.com/api'),
    headers: {
     "Content-Type": "application/x-www-form-urlencoded",
    },
    encoding: Encoding.getByName('utf-8'),
    body: {"title": "title"},
   );

 if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
   // then parse the JSON.
 } else {
    // If the server did not return a 200 OK response,
   // then throw an exception.
 }
}