24Flutter http原生网络请求

Flutter Http: http原生网络请求

1.json和String相互转换

Map userInfo = {
    "username":"张三",
    "age":20
}

json.decode(result.body); //json字符串(String) 转换为map
json.encode(userInfo); // map类型转换为String

2.http库

依赖:  http: ^0.12.2
GitHub:https://github.com/dart-lang/http   
安装:flutter packages get
导入:import 'package:http/http.dart' as http;
常用方法

get(dynamic url, { Map<String, String> headers }) → Future<Response>
(必须)url:请求地址
(可选)headers:请求头
    
post(dynamic url, { Map<String, String> headers, dynamic body, Encoding encoding }) → Future<Response>
(必须)url:请求地址
(可选)headers:请求头
(可选)body:参数
(编码)Encoding:编码 默认UTF-8
例子

3.自定义头信息

class UserAgentClient extends http.BaseClient {
  final String userAgent;
  final http.Client _inner;

  UserAgentClient(this.userAgent, this._inner);

  Future<http.StreamedResponse> send(http.BaseRequest request) {
    request.headers['user-agent'] = userAgent;
    return _inner.send(request);
  }
}

4.get请求


  _getData() async {
    var apiUrl = "http://a.itying.com/api/productlist";
    final http.Response result = await http.get(apiUrl); //
    if (result.statusCode == 200) {
      print(result.body);
      setState(() {
        /*
      {
        "result": [{
            "_id": "5ac0896ca880f20358495508",
            "title": "精选热菜",
            "pid": "0",
          }, {
            "_id": "5ac089e4a880f20358495509",
            "title": "特色菜",
            "pid": "0",

          }
        ]
      }
      */
        this._list = json.decode(result.body)["result"];
      });
    } else {
      print("失败${result.statusCode}");
    }
  }
返回信息:返回 http.Response

5.Post请求

1.普通Post请求,默认x-www-form-urlencoded ,和get请求区别不大
  _postData() async {
    var apiUrl = "http://192.168.0.5:3000/dologin";
    var result = await http.post(apiUrl, body: {'username': '张三', 'age': '20'});
    if (result.statusCode == 200) {
      print(json.decode(result.body));
    } else {
      print(result.statusCode);
    }
  }
2.Body请求,要设置ContentType.json
 //发送POST请求,application/json
  postJsonClient() async {
    var url = "https://abc.com:8090/path3";
    Map<String, String> headersMap = new Map();
    headersMap["content-type"] = ContentType.json.toString();
    Map<String, String> bodyParams = new Map();
    bodyParams["name"] = "value1";
    bodyParams["pwd"] = "value2";
    _client
        .post(url,
        headers: headersMap,
        body: jsonEncode(bodyParams),
        encoding: Utf8Codec())
        .then((http.Response response) {
      if (response.statusCode == 200) {
        print(response.body);
      } else {
        print('error');
      }
    }).catchError((error) {
      print('error');
    });
  }
3.MultipartRequest请求,默认是form-data
  // 发送POST请求,multipart/form-data
  postFormDataClient() async {
    var url = "https://abc.com:8090/path4";
    var client = new http.MultipartRequest("post", Uri.parse(url));
    client.fields["name"] = "value1";
    client.fields["pwd"] = "value2";
    client.send().then((http.StreamedResponse response) {
      if (response.statusCode == 200) {
        response.stream.transform(utf8.decoder).join().then((String string) {
          print(string);
        });
      } else {
        print('error');
      }
    }).catchError((error) {
      print('error');
    });
  }

4.上传文件
// 发送POST请求,multipart/form-data,上传文件
  postFileClient() async {
    var url = "https://abc.com:8090/path5";
    var client = new http.MultipartRequest("post", Uri.parse(url));
    http.MultipartFile.fromPath('file', 'sdcard/img.png',
        filename: 'img.png', contentType: MediaType('image', 'png'))
        .then((http.MultipartFile file) {
      client.files.add(file);
      client.fields["description"] = "descriptiondescription";
      client.send().then((http.StreamedResponse response) {
        if (response.statusCode == 200) {
          response.stream.transform(utf8.decoder).join().then((String string) {
            print(string);
          });
        } else {
          response.stream.transform(utf8.decoder).join().then((String string) {
            print(string);
          });
        }
      }).catchError((error) {
        print(error);
      });
    });
  }

解释一下MultipartRequest:MultipartRequest.send()返回的是StreamedResponse,和普通的Response还不一样

在MultipartRequest中,fields是一个Map;files是一个MultipartFile的List:
final Map<String, String> fields;
final List<MultipartFile> _files;
List<MultipartFile> get files => _files;
fields里存储的key-value就是body中的文本字段,key是name,value是内容。files里存储的就是需要上传的文件,MultipartFile有两个命名构造方法和一个静态方法:
factory MultipartFile.fromBytes(String field, List<int> value, {String filename, MediaType contentType})
factory MultipartFile.fromString(String field, String value, {String filename, MediaType contentType})
static Future<MultipartFile> fromPath(String field, String filePath, {String filename, MediaType contentType})
最后调用MultipartRequest中的send方法会将fields和files中的内容按照格式生成body,然后发送POST请求。
需要注意的是request.send()返回的是StreamedResponse,和普通的Response还不一样,需要用如下方法才能读取内容:
var respStr = await response.stream.transform(utf8.decoder).join();
LogUtil.i("upload response is $respStr");

6.Flutter请求抓包问题修复

Flutter请求抓包问题
一般做HTTP请求都会想要抓包来看一下请求的格式和内容对不对,但是这次连上代理以后发现其他请求都能抓到,只有Flutter里的请求抓不到…
上网搜索了一下,发现已经有人遇到过这个问题,并给出了解决方案,具体的分析这里就不再贴了,详情请看Flutter中http请求抓包解决方案。这里只写一下结论,增加如下代码就可以抓包了,"http_proxy"填代理PC的IP和端口即可。
var httpClient = new HttpClient();
httpClient.findProxy = (url) {
    return HttpClient.findProxyFromEnvironment(url, environment: {"http_proxy": 'http://192.168.124.7:8888',});
};
但是有一个问题,我们用的是http插件,不是原生的HttpClient,这又应该怎么设置呢?
遇事不决读源码,在http中的client.dart里,我看到这样的注释:
/// Creates a new client.
///
/// Currently this will create an `IOClient` if `dart:io` is available and
/// a `BrowserClient` if `dart:html` is available, otherwise it will throw
/// an unsupported error.
意思是如果有dart:io,就会创建一个IOClient;如果有dart:html,就会创建一个BrowserClient。HttpClient正是dart:io中的一员,所以我们来看看IOClient的实现:
/// The underlying `dart:io` HTTP client.
  HttpClient _inner;
  /// Creates a new HTTP client.
  IOClient([HttpClient inner]) : _inner = inner ?? new HttpClient();
这就很清晰了,IOClient实际就是HttpClient的封装,那我们只要自己创建一个HttpClient设置好代理后再创建IOClient就可以了,所以我们完整的上传代码就是:

  static Future<bool> upload(BaseUploadData data) async {
    var request = await data.getRequest();
    HttpClient httpClient = new HttpClient();
    httpClient.findProxy = (url) {
      return HttpClient.findProxyFromEnvironment(url, environment: {"http_proxy": 'http://10.45.109.70:8088',});
    };
    IOClient client = IOClient(httpClient);
    var response = await client.send(request);
    var respStr = await response.stream.transform(utf8.decoder).join();
    LogUtil.i("upload response is $respStr");
    return response.statusCode == 200;
  }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值