如何在flutter中使用url编码的主体发出HTTP POST请求?

Chi*_*ade 21 dart flutter

我正试图在内容类型为url编码的情况下发布帖子请求.当我写作时body : json.encode(data),它编码为纯文本.

如果我写,body: data我得到错误type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String' in type cast

这是数据对象

var match = {
  "homeTeam": {"team": "Team A"},
  "awayTeam": {"team": "Team B"}
};
Run Code Online (Sandbox Code Playgroud)

我的要求

var response = await post(Uri.parse(url),
    headers: {
      "Accept": "application/json",
      "Content-Type": "application/x-www-form-urlencoded"
    },
    body: match,
    encoding: Encoding.getByName("utf-8"));
Run Code Online (Sandbox Code Playgroud)

Ric*_*eap 18

您需要添加三个额外的步骤:首先,您需要将json映射转换为String(使用json.encode)然后,如果要将其作为application/x-www-form-urlencoded发送,则需要对其进行Uri编码.最后,您需要提供要发布名称的参数.

例如(注意,这是使用dart:io HttpClient,但它基本相同):

  Future<HttpClientResponse> foo() async {
    Map<String, dynamic> jsonMap = {
      'homeTeam': {'team': 'Team A'},
      'awayTeam': {'team': 'Team B'},
    };
    String jsonString = json.encode(jsonMap); // encode map to json
    String paramName = 'param'; // give the post param a name
    String formBody = paramName + '=' + Uri.encodeQueryComponent(jsonString);
    List<int> bodyBytes = utf8.encode(formBody); // utf8 encode
    HttpClientRequest request =
        await _httpClient.post(_host, _port, '/a/b/c');
    // it's polite to send the body length to the server
    request.headers.set('Content-Length', bodyBytes.length.toString());
    // todo add other headers here
    request.add(bodyBytes);
    return await request.close();
  }
Run Code Online (Sandbox Code Playgroud)

以上是针对dart:io版本(当然,你可以在Flutter中使用)如果你想坚持使用软件包:http版本,那么你需要稍微调整你的Map.body必须是Map <String,String>.您需要确定您想要的POST参数.你想要两个:homeTeam和awayTeam?还是一个,比如,teamJson?

这段代码

  Map<String, String> body = {
    'name': 'doodle',
    'color': 'blue',
    'homeTeam': json.encode(
      {'team': 'Team A'},
    ),
    'awayTeam': json.encode(
      {'team': 'Team B'},
    ),
  };

  Response r = await post(
    url,
    body: body,
  );
Run Code Online (Sandbox Code Playgroud)

在线上产生这个

名称=涂鸦&颜色=蓝色&homeTeam =%7B%22team%22%3A%22Team + A%22%7D&awayTeam =%7B%22team%22%3A%22Team + B%22%7D

或者,这个

  Map<String, String> body = {
    'name': 'doodle',
    'color': 'blue',
    'teamJson': json.encode({
      'homeTeam': {'team': 'Team A'},
      'awayTeam': {'team': 'Team B'},
    }),
  };

  Response r = await post(
    url,
    body: body,
  );
Run Code Online (Sandbox Code Playgroud)

在线上产生这个

名称=涂鸦&颜色=蓝色&teamJson =%7B%22homeTeam%22%3A%7B%22team%22%3A%22Team + A%22%7D%2C%22awayTeam%22%3A%7B%22team%22%3A%22Team + B %22%7D%7D

包:http客户端负责:编码Uri.encodeQueryComponent,utf8编码(请注意,这是默认值,因此无需指定)并在Content-Length标头中发送长度.您仍然必须执行json编码.


wen*_*ndu 13

我想向你推荐dio包,dio是Dart/Flutter的强大Http客户端,它支持Interceptor,FormData,Request Cancellation,File Downloading,Timeout等.

dio非常容易使用,在您的情况下,您可以:

Map<String, String> body = {
'name': 'doodle',
'color': 'blue',
'teamJson': {
  'homeTeam': {'team': 'Team A'},
  'awayTeam': {'team': 'Team B'},
  },
};

dio.post("/info",data:body, options: 
  new Options(contentType:ContentType.parse("application/x-www-form-urlencoded")))    
Run Code Online (Sandbox Code Playgroud)

dio可以自动编码数据.

更多细节请参考dio.


小智 8

你需要使用json.encode

例;

var match = {
  "homeTeam": {"team": "Team A"},
  "awayTeam": {"team": "Team B"}
};
var response = await post(Uri.parse(url),
    headers: {
      "Accept": "application/json",
      "Content-Type": "application/x-www-form-urlencoded"
    },
    body: json.encode(match),
    encoding: Encoding.getByName("utf-8"));
Run Code Online (Sandbox Code Playgroud)

  • 在 http/http.dart 中,如果我们使用 json.encode 对 body 进行编码,它将不起作用。只需将正文作为地图传递,它将使用编码将其编码为表单字段。 (2认同)

Sur*_*gch 7

我来这里只是想发出一个 HTTP POST 请求。以下是如何执行此操作的示例:

import 'dart:convert';
import 'package:http/http.dart';


makePostRequest() async {

  final uri = Uri.parse('http://httpbin.org/post');
  final headers = {'Content-Type': 'application/json'};
  Map<String, dynamic> body = {'id': 21, 'name': 'bob'};
  String jsonBody = json.encode(body);
  final encoding = Encoding.getByName('utf-8');

  Response response = await post(
    uri,
    headers: headers,
    body: jsonBody,
    encoding: encoding,
  );

  int statusCode = response.statusCode;
  String responseBody = response.body;
}
Run Code Online (Sandbox Code Playgroud)

也可以看看