简体   繁体   English

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

[英]How do you add query parameters to a Dart http request?

How do you correctly add query parameters to a Dart http get request?如何正确地将查询参数添加到 Dart http get 请求? I been unable to get my request to respond correctly when trying to append the '?param1=one&param2=two' to my url, yet it works correctly in Postman.尝试将“?param1=one&param2=two”附加到我的 url 时,我无法获得正确响应的请求,但它在 Postman 中正常工作。 Here's the gist of my code:这是我的代码的要点:

    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"},
);

The ${widget.pk} is simply a integer value being pass (See the value 123 in the workingStringInPostman variable. ${widget.pk} 只是一个传递的整数值(请参阅 workingStringInPostman 变量中的值 123。

The qParams is there for connivence, in case a Uri parameter is needed. qParams 是为了便利,以防需要 Uri 参数。

A code example would be welcomed.欢迎提供代码示例。

You'll want to construct a Uri and use that for the request.您需要构建一个Uri并将其用于请求。 Something like就像是

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

See https://api.dartlang.org/stable/2.0.0/dart-core/Uri/Uri.https.htmlhttps://api.dartlang.org/stable/2.0.0/dart-core/Uri/Uri.https.html

If you dont want to override the scheme of base endpoint url, use the below technique to convert the map to query string and append it to the base endpoint url如果您不想覆盖基本端点 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(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);

Got the same question.得到了同样的问题。 The accepted answer won't work if my url is localhost with port like https://localhost:5001 .如果我的 url 是 localhost 且端口类似于https://localhost:5001则接受的答案将不起作用。 After spending 1 day to search for solution, I come up with Dio library .在花了 1 天的时间寻找解决方案后,我想出了Dio 库 Following is my solution using 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);

Hope this helps.希望这可以帮助。

There is a dart package that provides some helper classes for http requests.有一个 dart 包为 http 请求提供了一些帮助类。

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

Install it with:安装它:

dependencies:
  basic_utils: ^1.4.0

Usage用法

You can add a map of headers and query parameters to each request.您可以向每个请求添加标头和查询参数的映射。 See the example :请参阅示例:

// 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);

Additional information :附加信息 :

These are all methods from the HttpUtils class.这些都是来自 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);

The accepted answer didn't work for me but adding a '&' without quotes to end of the URL solves my problem.接受的答案对我不起作用,但在 URL 末尾添加不带引号的“&”可以解决我的问题。 In this case, change the following line:在这种情况下,更改以下行:

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

to this: (Notice the '&' at the end).对此:(注意末尾的“&”)。

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

Use Uri constructor to build your query, it has a queryParameter property.使用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. 
}

this is more simpler这更简单

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

I made a little util function which resolves the authority / unencodedPath parameters for Uri creation.我做了一个小 util 函数,用于解析Uri创建的authority / unencodedPath参数。

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');
}

Here is the example code which uses it:这是使用它的示例代码:

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"
  },
);

Use Uri to pass query parameters like.使用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,
);

The following function copied from flutter code can be used to create the query string part only:从颤振代码复制的以下函数仅可用于创建查询字符串部分:

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();
}

Usage:用法:

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

U can use this:你可以用这个:

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}))
  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);
    }

this works as of today这从今天起有效

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM