如何向 Dart http 请求添加查询参数?

问题描述 投票:0回答:13

如何正确地将查询参数添加到 Dart http get 请求中?当尝试将 '?param1=one¶m2=two' 附加到我的网址时,我无法正确响应我的请求,但它在 Postman 中正常工作。这是我的代码的要点:

    final String url = "https://www.myurl.com/api/v1/test/";
    String workingStringInPostman = "https://www.myurl.com/api/v1/test/123/?param1=one&param2=two";

    Map<String, String> qParams = {
     'param1': 'one',
     'param2': 'two',
    };


   var res = await http
      .get(Uri.encodeFull("$url${widget.pk}/"),
      headers: {HttpHeaders.authorizationHeader: "Token $token", 
        HttpHeaders.contentTypeHeader: "application/json"},
);

${widget.pk} 只是一个正在传递的整数值(请参阅workingStringInPostman 变量中的值 123。

qParams 的存在是为了方便,以防需要 Uri 参数。

欢迎提供代码示例。

http get dart flutter url-parameters
13个回答
213
投票

您需要构造一个

Uri
并将其用于请求。类似的东西

final queryParameters = {
  'param1': 'one',
  'param2': 'two',
};
final uri =
    Uri.https('www.myurl.com', '/api/v1/test', queryParameters);
final response = await http.get(uri, headers: {
  HttpHeaders.authorizationHeader: 'Token $token',
  HttpHeaders.contentTypeHeader: ContentType.json.toString(),
});

参见 https://api.dartlang.org/stable/2.0.0/dart-core/Uri/Uri.https.html


53
投票

这个更简单

final uri = Uri.parse('$baseUrl/v1/endpoint').replace(queryParameters: {
      'page': page,
      'itemsPerPage': itemsPerPage,
    });
final response = await client.get(uri);

38
投票

如果您不想覆盖基本端点 url 的方案,请使用以下技术将映射转换为查询字符串并将其附加到基本端点 url

var endpointUrl = 'https://www.myurl.com/api/v1/user';
Map<String, String> queryParams = {
  'param1': '1',
  'param2': '2'
};

var headers = {
  HttpHeaders.authorizationHeader: 'Token $token',
  HttpHeaders.contentTypeHeader: 'application/json',
}

String queryString = Uri.parse(queryParameters: queryParams).query;

var requestUrl = endpointUrl + '?' + queryString; // result - https://www.myurl.com/api/v1/user?param1=1&param2=2
var response = await http.get(requestUrl, headers: headers);

8
投票

有同样的问题。如果我的网址是 localhost,端口如

https://localhost:5001
,则接受的答案将不起作用。花了 1 天寻找解决方案后,我想出了 Dio 库。以下是我使用
Dio
的解决方案:

var _dio = new Dio();
var options = new Options;
options.headers['Authorization'] = 'bearer $token';
options.contentType = 'application/json';
String url = "https://www.myurl.com";
Map<String, String> qParams = {
  'param1': 'one',
  'param2': 'two',
};

var res = await _dio.get(url, options: options, queryParameters: qParams);

希望这有帮助。


7
投票

使用

Uri
传递查询参数,例如。

final String url = "https://www.myurl.com/api/v1/test/${widget.pk}/";

Map<String, String> qParams = {
 'param1': 'one',
 'param2': 'two',
};
Map<String, String> header = {
HttpHeaders.authorizationHeader: "Token $token", 
    HttpHeaders.contentTypeHeader: "application/json"
};

Uri uri = Uri.parse(url);
final finalUri = uri.replace(queryParameters: qParams); //USE THIS

final response = await http.get(
  finalUri,
  headers: header,
);

6
投票

使用

Uri
构造函数来构建查询,它有一个
queryParameter
属性。

var uri = Uri(
  scheme: 'https',
  host: 'example.com',
  path: '/foo/bar',
  fragment: 'baz',
  queryParameters: _yourQueryParameters,
);

var response = await http.get(uri);
if (response.statusCode == 200) {
  var json = jsonDecode(response.body);
  // Do whatever you want to do with json. 
}

4
投票

接受的答案对我不起作用,但在 URL 末尾添加不带引号的“&”解决了我的问题。在这种情况下,请更改以下行:

String workingStringInPostman = "https://www.myurl.com/api/v1/test/123/?param1=one&param2=two";

对此:(注意末尾的“&”)。

String workingStringInPostman = "https://www.myurl.com/api/v1/test/123/?param1=one&param2=two&";

2
投票

有一个 dart 包为 http 请求提供了一些帮助器类。

BasicUtils:https://github.com/Ephenodrom/Dart-Basic-Utils

安装它:

dependencies:
  basic_utils: ^1.4.0

使用方法

您可以向每个请求添加标头和查询参数的映射。请参阅示例:

// Define some headers and query parameters
Map<String, String> headers = {
  "Accept": "application/json"
};
Map<String, String> queryParameters = {
  "foo": "bar"
};

// Body
String body = "{ 'some':'json'}";

// Send request
Map<String, dynamic> responseData = await HttpUtils.postForJson("api.com/dosomething", body,
      headers: headers, queryParameters: queryParameters);

附加信息:

这些都是 HttpUtils 类中的方法。

Future<Map<Response> getForFullResponse(String url,{Map<String, dynamic> queryParameters,Map<String, String> headers});
Future<Map<String, dynamic>> getForJson(String url,{Map<String, dynamic> queryParameters,Map<String, String> headers});
Future<String> getForString(String url,{Map<String, dynamic> queryParameters,Map<String, String> headers});
Future<Map<Response> postForFullResponse(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Map<String, dynamic>> postForJson(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<String> postForString(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Response> putForFullResponse(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Map<String, dynamic>> putForJson(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<String> putForString(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Response deleteForFullResponse(String url,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Map<String, dynamic>> deleteForJson(String url,{Map<String, String> queryParameters,Map<String, String> headers});
Future<String> deleteForString(String url,{Map<String, String> queryParameters,Map<String, String> headers});
Map<String, dynamic> getQueryParameterFromUrl(String url);
String addQueryParameterToUrl(String url, Map<String, dynamic> queryParameters);

1
投票

从 flutter 代码复制的以下函数只能用于创建查询字符串部分:

String queryString(Map<String, dynamic> queryParameters) {
  var result = StringBuffer();
  var separator = "";

  void writeParameter(String key, String? value) {
    result.write(separator);
    separator = "&";
    result.write(Uri.encodeQueryComponent(key));
    if (value != null && value.isNotEmpty) {
      result.write("=");
      result.write(Uri.encodeQueryComponent(value));
    }
  }

  queryParameters.forEach((key, value) {
    if (value == null || value is String) {
      writeParameter(key, value);
    } else {
      Iterable values = value;
      for (String value in values) {
        writeParameter(key, value);
      }
    }
  });
  return result.toString();
}

用途:

var q = queryString({"a":"b&", "c":["1","xyz"]});
// a=b%26&c=1&c=xyz

0
投票

我做了一个小 util 函数来解析

authority
/
unencodedPath
参数以创建
Uri

Uri createUri(String url, [Map<String, String> queryParameters]) {
  var isHttp = false;
  if (url.startsWith('https://') || (isHttp = url.startsWith('http://'))) {
    var authority = url.substring((isHttp ? 'http://' : 'https://').length);
    String path;
    final index = authority.indexOf('/');

    if (-1 == index) {
      path = '';
    } else {
      path = authority.substring(index);
      authority = authority.substring(0, authority.length - path.length);
    }

    if (isHttp) {
      return Uri.http(authority, path, queryParameters);
    } else {
      return Uri.https(authority, path, queryParameters);
    }
  } else if (url.startsWith('localhost')) {
    return createUri('http://' + url, queryParameters);
  }

  throw Exception('Unsupported scheme');
}

这是使用它的示例代码:

final String url = 'https://www.myurl.com/api/v1/test/${widget.pk}';
Map<String, String> qParams = {
  'param1': 'one',
  'param2': 'two',
};

var res = await http.get(
  createUri(url, qParams),
  headers: {
    HttpHeaders.authorizationHeader: "Token $token",
    HttpHeaders.contentTypeHeader: "application/json"
  },
);

0
投票

你可以用这个:

String _getParamsFromBody( Map<String, dynamic>? body) {
String params = '?';
for (var i = 0; i < body!.keys.length; i++) {
  params += '${List.from(body!.keys)[i]}=${List.from(body!.values)[i]}';
  if (i != body!.keys.length - 1) {
    params += '&';
  }
}
log(params);
return params;

}

Uri.parse("https://www.myurl.com/api/v1/test"+ _getParamsFromBody({'param1':'value1','param2':'value2}))

0
投票
  final uri = Uri.parse("${ApiConstants.baseUrl}/blog/post/blog-post-list");
  uri.replace(queryParameters: {"location": location});
  final Response response = await _apiRepository.getApi(uri);
  if (response.statusCode == 200 || response.statusCode == 201) {
    final content = await jsonDecode(response.body);
    final data = await content["data"] as List;
    List<PostModel> list = [];
    for (var i in data) {
      final postModel = PostModel.fromJson(i);
      list.add(postModel);
    }

从今天开始有效


-1
投票

这对我有用。

  _init() async {
    DateTime endDate = DateTime.now();
    DateTime startDate = endDate.subtract(Duration(days: 30 * 11));
    var response = await Api.get(
        "mover/dashboard/column-chart?start=$startDate&end=$endDate");
    if (response.statusCode == 200) {
      var json = jsonDecode(response.body);
      if (mounted) {
        setState(() {});
      }
    }
  }

API.dart

  static Future<http.Response> get(path) async {
    String? token = await Store.read('token');
    try {
      var response = await http.get(
        Uri.parse('$basePath/api/moving/$path'),
        headers: {
          'Authorization': 'Bearer $token',
          'Content-Type': 'application/json'
        },
      );
      return response;
    } catch (err) {
      return http.Response('${err.toString()}', 400);
    }
  }
© www.soinside.com 2019 - 2024. All rights reserved.