如何在 Flutter 中发布 x-www-form-urlencoded

Ely*_*nad 6 http-post dart flutter x-www-form-urlencoded

我正在尝试向POSTAPI发送请求以创建帐户。
请求运行良好,它应该是这样的:

批量编辑模式:
批量编辑模式

键值编辑模式:
键值编辑模式

还有 9 个标题是自动生成的,所以我没有显示它们,但如果您需要,我可以使用另一个屏幕。

我的请求是这样的:

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) ;

}
Run Code Online (Sandbox Code Playgroud)

这是我的打印结果:

I/flutter ( 6942): RESPONSE 307 ; BODY =  
Run Code Online (Sandbox Code Playgroud)

如您所见,我收到 307 错误,并且问题不是来自服务器,因为它与 Postman 一起工作。

form-urlencoded POST是否正确发送了此请求?

我也试过:

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"),
  );
Run Code Online (Sandbox Code Playgroud)

但结果相同。我也试过:

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

同样的结果。
我究竟做错了什么 ?

编辑 :

我尝试了 FoggyDay 答案,这是我现在的要求:

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}");
Run Code Online (Sandbox Code Playgroud)

但是我仍然有 307 错误。我是否创建了正确的请求?

编辑 2:

正如所问,我打印的位置如下:

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}");
Run Code Online (Sandbox Code Playgroud)

我得到:

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
Run Code Online (Sandbox Code Playgroud)

问题是我已经在 /app/createUser 上打电话了......('/app/' 在 BASE_URL 中)

Par*_*ani 21

对于x-www-form-urlencoded参数,只需使用这个:

  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.
 }
}
Run Code Online (Sandbox Code Playgroud)


Ali*_*i80 8

flutter 的官方http包在类型上有问题urlencoded,您可以使用Dio包代替。

final dio = Dio();
final res = dio.post(
  '/info',
  data: {'id': 5},
  options: Options(contentType: Headers.formUrlEncodedContentType),
);
Run Code Online (Sandbox Code Playgroud)

  • 不适合我 (2认同)

pau*_*sm4 1

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

不,情况不一定如此。看这里:

MDN:307 临时重定向

换句话说,Postman 正在遵循重定向……而您的 Flutter 应用程序则不然。

建议:尝试设置followRedirects为 true:

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


附加信息:

  • 无论如何,默认值request.followRedirects恰好是“true”。明确设置它并没有什么坏处......但它解释了为什么行为没有改变。

  • 根据这篇文章

Dart HTTP 客户端不会遵循 POST 重定向,除非响应代码为 303。它遵循 GET 或 HEAD 的 302 重定向。

处理 POST 请求重定向的正确方法是针对您的用例手动实施适当的策略:

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