How to make HTTP POST request with url encoded body in flutter?

前端 未结 8 1530
南笙
南笙 2020-12-01 03:59

I\'m trying to make an post request in flutter with content type as url encoded. When I write body : json.encode(data), it encodes to plain text.

If I

8条回答
  •  没有蜡笔的小新
    2020-12-01 04:05

    You need to add three additional steps: First, you need to convert the JSON map to a String (using json.encode) Then you need to Uri encode it if you want to send it as application/x-www-form-urlencoded. Lastly, you need to give the parameter that you are posting a name.

    For example (note, this is using the dart:io HttpClient, but it's basically the same):

      Future foo() async {
        Map 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 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();
      }
    

    The above is for the dart:io version (which, of course, you can use in Flutter) If you would like to stick with the package:http version, then you need to tweak your Map a bit. body must be a Map. You need to decide what you want as your POST parameters. Do you want two: homeTeam and awayTeam? or one, say, teamJson?

    This code

      Map body = {
        'name': 'doodle',
        'color': 'blue',
        'homeTeam': json.encode(
          {'team': 'Team A'},
        ),
        'awayTeam': json.encode(
          {'team': 'Team B'},
        ),
      };
    
      Response r = await post(
        url,
        body: body,
      );
    

    produces this on the wire

    name=doodle&color=blue&homeTeam=%7B%22team%22%3A%22Team+A%22%7D&awayTeam=%7B%22team%22%3A%22Team+B%22%7D

    alternatively, this

      Map body = {
        'name': 'doodle',
        'color': 'blue',
        'teamJson': json.encode({
          'homeTeam': {'team': 'Team A'},
          'awayTeam': {'team': 'Team B'},
        }),
      };
    
      Response r = await post(
        url,
        body: body,
      );
    

    produces this on the wire

    name=doodle&color=blue&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

    the package:http client takes care of: encoding the Uri.encodeQueryComponent, utf8 encoding (note that that's the default, so no need to specify it) and sending the length in the Content-Length header. You must still do the json encoding.

提交回复
热议问题