如何通过Flutter发布到Google表单响应始终为400POSTMAN的结果为200 OK

问题描述

我试图用Flutter发布到Google表单,但响应始终为400。 当我使用POSTMAN时,它会成功。 我不明白为什么它会随着颤动而失败。

我尝试使用Http包dio包,但结果始终为400。 问题是什么?如果有解决此问题的建议,请告诉我。

我尝试的代码如下。

  1. http软件包(http:^ 0.12.2)
void _request() async {
    String url =
        'https://docs.google.com/forms/u/0/d/e/1FAIpQLSc5aAwiiLJ2qJhF-ngGFfRl8m8yEJs8gTipY7pnNQkxGcJ_1w/formResponse';

    Map<String,String> headers = {
      "Content-Type": "application/x-www-form-urlencoded",};
    String body = json.encode(
      {
        'entry.844954850': 'bug','entry.479013015': 'dsfa',},);
    http.Response resp = await http.post(url,headers: headers,body: body);
    if (resp.statusCode != 200) {
      print('Failed to post ${resp.statusCode}');
    } else {
      print(resp.body);
    }
  }

结果是

I/Flutter ( 5834): Failed to post 400
  1. dio软件包(dio:^ 3.0.10)
Future _request_dio() async {
    final dio = dio();
    final url =
        'https://docs.google.com/forms/u/0/d/e/1FAIpQLSc5aAwiiLJ2qJhF-ngGFfRl8m8yEJs8gTipY7pnNQkxGcJ_1w/formResponse';

    String body = json.encode(
      {
        'entry.844954850': 'bug',);

    var data = await dio
        .post(
      url,data: body,options: Options(contentType: Headers.formUrlEncodedContentType),)
        .then((response) {
      print(response.data);
      return response.data;
    }).catchError((err) {
      print(err);
      return null;
    });
  }

结果是

I/Flutter ( 5834): dioError [dioErrorType.RESPONSE]: Http status error [400]

当我使用POSTMAN成功后,在POSTMAN中使用了以下HTTP代码

POST /forms/u/0/d/e/1FAIpQLSc5aAwiiLJ2qJhF-ngGFfRl8m8yEJs8gTipY7pnNQkxGcJ_1w/formResponse HTTP/1.1
Host: docs.google.com
Content-Type: application/x-www-form-urlencoded
Cookie: S=spreadsheet_forms=yClaqeCIC2953sdlxK8fzZb97ycQG4UFviYCNtUBFtg; NID=204=vu3hzpnGl1iqwJCJgR_bPkjmqdx4uvEQYIfxgZWm9sc6KJjoOSZDFpMrSn0AtlmqjJeFb0JkX6MJnpIHtYXgXebI7CbKJy4JI_1hOfFe8fiMjM6qEbKw4BhNjaDzHyKTk6uoU4mpG34i01A2rEbch7xCs6Z_cvwfPhNvFWH_xGI

entry.844954850=bug&entry.479013015=fsda

扑扑医生的结果是

C:\src\Flutter\bin\Flutter.bat doctor --verbose
[√] Flutter (Channel stable,1.20.4,on Microsoft Windows [Version 10.0.18363.1082],locale ja-JP)
    • Flutter version 1.20.4 at C:\src\Flutter
    • Framework revision fba99f6cf9 (5 days ago),2020-09-14 15:32:52 -0700
    • Engine revision d1bc06f032
    • Dart version 2.9.2

[√] Android toolchain - develop for Android devices (Android SDK version 30.0.1)
    • Android SDK at C:\Users\user\AppData\Local\Android\sdk
    • Platform android-30,build-tools 30.0.1
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
    • All Android licenses accepted.

[√] Android Studio (version 4.0)
    • Android Studio at C:\Program Files\Android\Android StudioFlutter plugin version 48.1.2
    • Dart plugin version 193.7547
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)

解决方法

在Postman中用表格数据重现案件后: postman

为了控制,我使用curl进行测试:

curl --location --request POST 'https://docs.google.com/forms/u/0/d/e/1FAIpQLSc5aAwiiLJ2qJhF-ngGFfRl8m8yEJs8gTipY7pnNQkxGcJ_1w/formResponse' \
    --form 'entry.844954850=bug' \
    --form 'entry.479013015=dsfa'

现在我可以在颤抖中重现此Post请求:

void _request() async {
  String url =
      'https://docs.google.com/forms/u/0/d/e/1FAIpQLSc5aAwiiLJ2qJhF-ngGFfRl8m8yEJs8gTipY7pnNQkxGcJ_1w/formResponse';

  Map<String,String> headers = {
    "Content-Type": "application/x-www-form-urlencoded",};
  // String body = json.encode(...)      //------------> Before
  Map<String,String> requestBody = <String,String>{ // After
    'entry.844954850': 'bug','entry.479013015': 'dsfa'
  };

  http.Response resp =
      await http.post(url,headers: headers,body: requestBody);
  print(resp);
  if (resp.statusCode != 200) {
    print('Failed to post ${resp.statusCode}');
  } else {
    print(resp.body);
  }
}

调试模式下的状态代码:

result

对于dio,它与替换json相同,并且您的请求格式正确。