http请求requestInStream接口如何使用
===========================

#### 问题现象

http请求requestInStream接口如何获取响应数据？

#### 背景知识

[requestInStream](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-http#requestinstream10)可以根据URL地址，发起http网络请求并返回流式响应。

#### 解决方案

使用[requestInStream](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-http#requestinstream10)接口需要注意，callback回调返回的是number类型的数据，也就是响应码，不会返回具体的数据，可通过[on("dataReceive")](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-http#ondatareceive10)接收响应数据，当订阅成功时，error为undefined，data为接收到的http流式数据，类型为ArrayBuffer；否则为错误对象。

import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

class Header {
  public contentType: string;

  constructor(contentType: string) {
    this.contentType \= contentType;
  }
}

function createAndRequest() {
  let httpRequest \= http.createHttp();
  let options: http.HttpRequestOptions \= {
    method: http.RequestMethod.POST, _// 可选，默认为http.RequestMethod.GET。_
  _  // 当使用POST请求时此字段用于传递请求体内容，具体格式与服务端协商确定。_
    extraData: 'data to send',
    expectDataType: http.HttpDataType.STRING, _// 可选，指定返回数据的类型。_
    usingCache: true, _// 可选，默认为true。_
    priority: 1, _// 可选，默认为1。_
   _ // 开发者根据自身业务需要添加header字段。_
    header: new Header('application/json'),
    readTimeout: 60000, _// 可选，默认为60000ms。_
    connectTimeout: 60000, _// 可选，默认为60000ms。_
    usingProtocol: http.HttpProtocol.HTTP1\_1, _// 可选，协议类型默认值由系统自动指定。_
    usingProxy: false, _// 可选，默认不使用网络代理，自API 10开始支持该属性。_
  };
  httpRequest.requestInStream('EXAMPLE\_URL', options, (err: BusinessError<void\>, data: number) \=\> {
    if (!err) {
      console.info('requestInStream OK! ResponseCode is ' \+ JSON.stringify(data));
    } else {
      console.error('requestInStream ERROR : err = ' \+ JSON.stringify(err));
    }
  });
  httpRequest.on('dataReceive', (data: ArrayBuffer) \=\> {
    console.info('dataReceive length: ' \+ JSON.stringify(data.byteLength));
  });
  httpRequest.on('dataEnd', () \=\> {
    console.info('Receive dataEnd !');
    httpRequest.destroy();
  });
}

@Entry
@Component
struct Index {
  build() {
    RelativeContainer() {
      Button('click')
        .id('HelloWorld')
        .fontSize($r('app.float.page\_text\_font\_size'))
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '\_\_container\_\_', align: VerticalAlign.Center },
          middle: { anchor: '\_\_container\_\_', align: HorizontalAlign.Center }
        })
        .onClick(() \=\> {
          createAndRequest();
        });
    }
    .height('100%')
    .width('100%');
  }
}

当所有数据接收完毕后，on('dataEnd', () => {})方法会被调用，标志着数据接收完成。在使用完http请求对象后，调用destroy()方法来主动销毁这个对象，避免资源泄露。

#### 总结

requestInStream接口是用于处理http请求返回的流式数据的方法。在HarmonyOS中，当http请求的响应数据量较大时，比如超过5M、100M，使用requestInStream可以有效地处理这些数据，避免内存溢出等问题。

#### 常见FAQ

Q：http发起的requestInStream流式请求，dataReceiveProgress无回调。

A：服务端需返回Content-Length字段，不然没有数据长度，dataReceiveProgress也就不会被触发。