Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.1k views
in Technique[技术] by (71.8m points)

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

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)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

No, that's NOT necessarily the case. Look here:

MDN: 307 Temporary Redirect

In other words, Postman is following the redirect ... and your Flutter app isn't.

SUGGESTION: Try setting followRedirects to true:

https://api.flutter.dev/flutter/dart-io/HttpClientRequest/followRedirects.html


ADDITIONAL INFO:

  • The default value for request.followRedirects happens to be "true" anyway. It doesn't hurt to explicitly set it ... but it explains why the behavior didn't change.

  • Per this post:

The Dart HTTP client won't follow redirects for POSTs unless the response code is 303. It follows 302 redirects for GET or HEAD.

The correct way to handle redirects on POST requests is to manually implement an appropriate strategy for your use case:

  var response = await client.post(...);
  if (response.statusCode == 301 || response.statusCode == 302) {
    // send post request again if appropriate
  }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...