如何在Flutter中解码Gzip Http响应?

9

我是Flutter的新手。我正在进行一个网络请求,我得到了正确的响应,但数据经过了Gzip压缩。我已经在Swift中解压了相同的数据,但是在Flutter中,我无法做到这一点。有人可以帮帮我吗?

以下是我尝试过的内容:

import 'dart:convert';
import 'package:http/http.dart';
import 'package:archive/archive.dart';
import 'package:flutter_app/Constants/constants.dart';

class ServiceHelper {

  static final sharedInstance = ServiceHelper();

  Future<Response> sendRequest({String path, Map<String,dynamic> params}) async {

    final String url = Constants.testURL+path;

    var body = jsonEncode(params);

    Response response = await post(url, body:body);

    final gZipped_data = GZipDecoder().decodeBytes(response.bodyBytes);

    print(gZipped_data); //flutter: [123, 34, 115, 116, 97, 116, 117, 115, 34, 58, 50, 48, 48, 44, 34, 109, 101, 115, 115, 97, 103, 101, 34, 58, 34, 83, 105, 103, 110, 32, 105, 110, 32, 67, 111, 109, 112, 108, 101, 116, 101, 100, 32, 83, 117, 99, 99, 101, 115, 115, 102, 117, 108, 108, 121, 34, 44, 34, 100, 97, 116, 97, 34, 58, 123, 34, 117, 115, 101, 114, 95, 105, 110, 102, 111, 34, 58, 123, 34, 112, 108, 97, 121, 101, 114, 95, 105, 100, 34, 58, 49, 52, 56, 54, 57, 44, 34, 112, 108, 95, 97, 112, 112, 95, 105, 100, 34, 58, 34, 57, 90, 104, 57, 82, 66, 108, 70, 34, 44, 34, 112, 114, 111, 102, 105, 108, 101, 95, 112, 105, 99, 34, 58, 34, 104, 116, 116, 112, 115, 58, 92, 47, 92, 47, 119, 119, 119, 46, 115, 112, 111, 114, 116, 115, 113, 119, 105, 122, 122, 46, 99, 111, 109, 92, 47, 118, 51, 92, 47, 105, 109, 103, 92, 47, 112, 108, 97, 121, 101, 114, 115, 92, 47, 112, 105, 99, 92, 47, 105, 80, 45, 49, 53, 50, 51, 56, 54, 57, 50, 57, 56, 46, 112, 110, 103, 34, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 116, 101, 99, 104, 121, <…>


   //This throws an error: Unhandled Exception: FormatException: Bad UTF-8 encoding 0x8b (at offset 1)

    return response;

  }


}

//This is the login function and it is in a different file main.dart

 Future<void> login(
      {String email,
      String name,
      int source,
      String sourceStr,
      String picString,
      String idToken}) async {
    final String playerID = '';

    final String token = await getIOSToken().then((token){

      return token;

    });

    Map<String, dynamic> params = {
      "email": email,
      "name": name,
      "player_id": playerID,
      "source_id": source,
      "profile_pic": picString,
      "password": passwordController.text ?? "",
      "ios_token":token,
      "device_type": "I",
      "language_iso": "en",
      "referred_by": "loginDefault",
      "firebase_id_token": idToken,
      "app_version": "4.4.9"
    };

    Response response = await ServiceHelper.sharedInstance
        .sendRequest(path: Constants.login, params: params);

    if (response.statusCode == 201) {
      // If server returns an OK response, parse the JSON.
      return UserDetails.fromJson(json.decode(response.body));
    } else {
      // If that response was not OK, throw an error.
      throw Exception('Failed to load post');
    }
  }

期望的响应是JSON,但由于它被Gzipped压缩了,我无法解压它,不知道如何从中获取JSON。我已经尝试解码它,并给出了一个名为gzipped_data的整数列表,正如你在上面看到的。我该如何从中获取JSON?

2个回答

3

此外,HttpClient 将自动添加 Accept-Encoding: gzip 标头。请参见:https://api.flutter.dev/flutter/dart-io/HttpClient-class.html#headers - mtkopone

3

我正在使用来自 dart:ioGZipCodec

如果想将响应作为 String 返回,请按以下方式尝试。

Future<String> sendRequest({String path, Map<String,dynamic> params}) async {

    final String url = Constants.testURL+path;

    var body = jsonEncode(params);

    Response response = await post(url, body:body);

    final decoded_data = GZipCodec().decode(response.bodyBytes);


    return utf8.decode(decoded_data, allowMalformed: true);

  }

这听起来像是正确的答案,但是我收到了“FormatException (FormatException: 过滤器错误,数据不良)”的错误信息。 - Christian Findlay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接