Dart网络编程(二)

一、Uri

Uri 类 提供了 编码和解码 URI(URL) 字符的功能。 这些函数处理 URI 特殊的字符,例如 & 和 =。 Uri 类还可以解析和处理 URI 的每个部分,比如 host, port, scheme 等。

1.1.Encoding and decoding fully qualified URIs(编码解码URI)

要编码和解码除了 URI 中特殊意义(例如 /:&,#)的字符, 则可以使用 encodeFull() 和 decodeFull() 函数。这两个函数可以用来编码和解码整个 URI,并且保留 URI 特殊意义的字符不变。

var uri = 'http://example.org/api?foo=some message';

var encoded = Uri.encodeFull(uri);
assert(encoded ==
    'http://example.org/api?foo=some%20message');

var decoded = Uri.decodeFull(encoded);
assert(uri == decoded);

注意:上面 some 和 message 之间的空格被编码了。

1.2.Encoding and decoding URI components(编码解码URI组件)

使用encodeComponent() 和 decodeComponent() 可以编码 和解码 URI 中的所有字符,特殊意义的字符(/&, 和:等) 也会编码,

var uri = 'http://example.org/api?foo=some message';

var encoded = Uri.encodeComponent(uri);
assert(encoded ==
    'http%3A%2F%2Fexample.org%2Fapi%3Ffoo%3Dsome%20message');

var decoded = Uri.decodeComponent(encoded);
assert(uri == decoded);

注意:上面特殊字符也被编码了,比如 / 编码为 %2F

1.3.Parsing URIs

如果有个 Uri 对象或者 URI 字符串,使用 Uri 的属性 可以获取每个部分,比如 path。使用 parse() 静态 函数可以从字符串中解析一个 Uri 对象:

var uri = Uri.parse('http://example.org:8080/foo/bar#frag');

assert(uri.scheme   == 'http');
assert(uri.host     == 'example.org');
assert(uri.path     == '/foo/bar');
assert(uri.fragment == 'frag');
assert(uri.origin   == 'http://example.org:8080');

1.4.Building URIs

使用 Uri() 构造函数可以从 URI 的 各个部分来构造一个 Uri 对象:

var uri = new Uri(scheme: 'http', host: 'example.org',
                  path: '/foo/bar', fragment: 'frag');
assert(uri.toString() ==
    'http://example.org/foo/bar#frag');

更多信息参考 Uri API 文档 。

二、dart原生网络请求API

原生API使用的是用dart:io中的HttpClient发起的请求,但HttpClient本身功能较弱,很多常用功能都不支持。

HTTP API 在返回值中使用了Dart Futures。 建议使用async/await语法来调用API。

网络调用通常遵循如下步骤:

  • 1、创建 client.
  • 2、构造 Uri.
  • 3、发起请求, 等待请求,同时您也可以配置请求headers、 body。
  • 4、关闭请求, 等待响应.
  • 5、解码响应的内容.

以下示例对HTTPS GET请求返回的JSON数据进行解码:

import 'dart:async';
import 'dart:io';
import 'dart:convert'; // 使用dart:convert内置库可以简单解码和编码JSON



_getIPAddress() async {
    var url = 'https://httpbin.org/ip';
    // 1.创建 client.
    var httpClient = new HttpClient();
    // 2.构造 Uri.
    var uri = Uri.parse(url);

    String result;
    try {
      // 3.发起请求, 等待请求,同时您也可以配置请求headers、 body。
      var request = await httpClient.getUrl(uri);
      // 4.关闭请求, 等待响应.
      var response = await request.close();
      if (response.statusCode == HttpStatus.ok) {
       // 5.解码响应的内容.
        var json = await response.transform(utf8.decoder).join();
        var data = jsonDecode(json);
        result = data['origin'];
      } else {
        result =
        'Error getting IP address:\nHttp status ${response.statusCode}';
      }
    } catch (exception) {
      result = 'Failed getting IP address';
    }
    print(result); // 14.147.104.242, 14.147.104.242

三、使用第三方库http

http包含一组高级函数和类,可以方便地使用HTTP资源。它与平台无关,可以在命令行和浏览器上使用。

3.1.库的安装

  • 1、在pubspec.yaml文件添加这个包的依赖:
dependencies:
  http: ^0.12.0+2
  • 2、通过命令行pub命令安装包
pub get

如果你装了Flutter插件也可以用以下令(也可通过用户交互界面安装,如Visual Studio Code、Android Studio装了Flutter插件):

flutter packages get

3.2.库的使用

使用这个库最简单的方法是通过顶级函数。它们允许你以最便捷的方式发出单独的HTTP请求:

import 'package:http/http.dart' as http;

var url = 'http://example.com/whatsit/create';
var response = await http.post(url, body: {'name': 'doodle', 'color': 'blue'});
print('Response status: ${response.statusCode}');
print('Response body: ${response.body}');

print(await http.read('http://example.com/foobar.txt'));

如果向同一服务器发出多个请求,可以使用Client而不是一次性请求来保持打开持久连接。如果您这样做,请确保在完成时关闭client。

var client = new http.Client();
try {
  var uriResponse = await client.post('http://example.com/whatsit/create',
      body: {'name': 'doodle', 'color': 'blue'});
  print(await client.get(uriResponse.bodyFields['uri']));
} finally {
  client.close();
}

您还可以通过自己创建Request 或StreamedRequest 对象并将其传递给Client.send来对请求和响应施加更详细的控制。

这个包被设计成可组合的。这使得外部库可以很容易地相互协作,向其添加行为。希望添加行为的库应该创建

猜你喜欢

转载自blog.csdn.net/it_lanmei/article/details/128200326