13

我正在尝试向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) ;

}

这是我的打印结果:

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

如您所见,我收到 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"),
  );

但结果相同。我也试过:

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

再次得到相同的结果。
我究竟做错了什么 ?

编辑 :

我尝试了 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}");

但是我仍然有一个 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}");

我得到:

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

问题是我已经在调用 /app/createUser...('/app/' 在 BASE_URL 中)

4

4 回答 4

8

对于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.
 }
}
于 2021-05-24T12:50:42.023 回答
3

Flutter 的官方httpurlencoded类型有问题,你可以使用Dio包代替。

final dio = Dio();
final res = dio.post(
  '/info',
  data: {'id': 5},
  options: Options(contentType: Headers.formUrlEncodedContentType),
);
于 2021-12-21T12:20:47.547 回答
2

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为真:

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


附加信息:

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

  • 根据这篇文章

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

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

  var response = await client.post(...);
  if (response.statusCode == 301 || response.statusCode == 302) {
    // send post request again if appropriate
  }
于 2020-05-25T23:58:39.530 回答
0

如果您使用的是 http,则应添加以下行

安卓-

android/app/src/main/AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<application
        android:label="first_app"
        android:usesCleartextTraffic="true" //this line
        android:icon="@mipmap/ic_launcher">

iOS -

ios/Runner/info.plist

<key>NSAppTransportSecurity</key>
<dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
</dict>

请注意,启用此功能时,您需要向 Apple 的审核团队做出解释,否则,您的应用将在提交时被拒绝。

如果您在添加这些行时已经在模拟器中安装了该应用程序,请卸载该应用程序并重新安装以避免混淆。

如果发送 HTTP GET 请求,可以使用如下查询参数:

查询参数

http://example.com/path/to/page?name=ferret&color=purple

  • 内容被编码为 URL 中的查询参数

应用程序/x-www-form- urlencoded

  • 内容被编码为请求正文中的查询参数,而不是 URL。

  • 数据作为长查询字符串发送。查询字符串包含由 & 字符分隔的名称-值对

发布示例

Flutter http 包版本 - http: ^0.13.1

import 'package:http/http.dart' as httpClient;


Future<dynamic> postData() async {
    //Uri.https("192.168.1.30:5000", "/api/data")
    //Uri.parse("your url");
    final Uri uri = Uri.http("192.168.1.30:5000", "/api/data");
    final response = await httpClient.post(
      uri,
      body: {
        "name": "yourName",
        "age": "yourAge"
      },
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
      },
      encoding: Encoding.getByName('utf-8'),
    );
    return response.body;
  }
于 2021-05-16T18:03:25.037 回答