【问题标题】:How do you add query parameters to a Dart http request?如何将查询参数添加到 Dart http 请求中?
【发布时间】:2019-03-20 07:59:47
【问题描述】:

如何正确地将查询参数添加到 Dart http get 请求中?尝试将 '?param1=one&param2=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


    【解决方案1】:

    您需要构造一个Uri 并将其用于请求。类似的东西

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

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

    【讨论】:

    • 主机和路径的拆分就是答案。
    • 这里的widget.pk是什么
    • 由于某种原因,应用程序在Uri.https 之后像异常一样停止,但没有错误,它就停止了。
    • 如果 url 是带有 localhost:5001 之类端口的本地主机,则会出错。
    • 不适用于本地地址定义 api 路径
    【解决方案2】:

    如果您不想覆盖基本端点 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);
    

    【讨论】:

    • 不幸的是,这不再起作用了。在http.get(requestUrl....) The argument type 'String' can't be assigned to the parameter type 'Uri'. 处抛出错误
    • @OjonugwaJudeOchalifu 只需将字符串包装在 Uri.parse() 中。
    【解决方案3】:

    有同样的问题。如果我的 url 是带有 https://localhost:5001 之类的端口的 localhost,则接受的答案将不起作用。在花了 1 天时间寻找解决方案后,我想出了Dio library。以下是我使用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);
    

    希望这会有所帮助。

    【讨论】:

    • 仍然出现此错误 - 未处理的异常:NoSuchMethodError:在 null 上调用了方法“[]”。 E/flutter (12741):接收者:null E/flutter (12741):尝试调用:[]("BankName")
    • 您能提出任何解决方案吗?
    • 为了获得List&lt;String&gt; 的响应,我必须使用_dio.get&lt;List&lt;dynamic&gt;&gt;(...).data.cast&lt;String&gt;();。如果有人知道更好的方法,请随时告诉我。
    • 应该是options.headers = {'Authorization': 'bearer $token'};
    【解决方案4】:

    这样更简单

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

    【讨论】:

      【解决方案5】:

      有一个 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);
      

      【讨论】:

        【解决方案6】:

        接受的答案对我不起作用,但在 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&";
        

        【讨论】:

        • 最简单最好的解决方案)
        【解决方案7】:

        使用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. 
        }
        

        【讨论】:

          【解决方案8】:

          我制作了一个小 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"
            },
          );
          

          【讨论】:

            【解决方案9】:

            使用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,
            );
            

            【讨论】:

              猜你喜欢
              • 2015-07-20
              • 1970-01-01
              • 2021-06-04
              • 1970-01-01
              • 2019-11-29
              • 2020-05-11
              • 2014-06-15
              • 2021-02-25
              • 2019-12-18
              相关资源
              最近更新 更多