• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# HTTP Data Request
2
3## When to Use
4
5An application can initiate a data request over HTTP. Common HTTP methods include **GET**, **POST**, **OPTIONS**, **HEAD**, **PUT**, **DELETE**, **TRACE**, and **CONNECT**.
6
7<!--RP1-->
8
9<!--RP1End-->
10
11## Available APIs
12
13The HTTP request function is mainly implemented by the HTTP module.
14
15To use related APIs, you must declare the **ohos.permission.INTERNET** permission.
16
17For details about how to apply for permissions, see [Declaring Permissions](../security/AccessToken/declare-permissions.md).
18
19The following table provides only a simple description of the related APIs. For details, see [API Reference](../reference/apis-network-kit/js-apis-http.md).
20
21| API                                   | Description                               |
22| ----------------------------------------- | ----------------------------------- |
23| createHttp()                              | Creates an HTTP request.                 |
24| request()                                 | Initiates an HTTP request to a given URL.    |
25| requestInStream()<sup>10+</sup>           | Initiates an HTTP network request to a given URL and returns a streaming response.|
26| destroy()                                 | Destroys an HTTP request.                     |
27| on(type: 'headersReceive')                | Registers an observer for HTTP Response Header events.    |
28| off(type: 'headersReceive')               | Unregisters the observer for HTTP Response Header events.|
29| once\('headersReceive'\)<sup>8+</sup>     | Registers a one-time observer for HTTP Response Header events.|
30| on\('dataReceive'\)<sup>10+</sup>         | Registers an observer for events indicating receiving of HTTP streaming responses.     |
31| off\('dataReceive'\)<sup>10+</sup>        | Unregisters the observer for events indicating receiving of HTTP streaming responses. |
32| on\('dataEnd'\)<sup>10+</sup>             | Registers an observer for events indicating completion of receiving HTTP streaming responses. |
33| off\('dataEnd'\)<sup>10+</sup>            | Unregisters the observer for events indicating completion of receiving HTTP streaming responses.|
34| on\('dataReceiveProgress'\)<sup>10+</sup>        | Registers an observer for events indicating progress of receiving HTTP streaming responses. |
35| off\('dataReceiveProgress'\)<sup>10+</sup>       | Unregisters the observer for events indicating progress of receiving HTTP streaming responses.|
36| on\('dataSendProgress'\)<sup>11+</sup>        | Registers an observer for events indicating progress of sending HTTP requests. |
37| off\('dataSendProgress'\)<sup>11+</sup>       | Unregisters the observer for events indicating progress of sending HTTP requests.|
38
39## Initiating an HTTP Data Request
40
411. Import the **http** namespace from **@kit.NetworkKit**.
422. Call **createHttp()** to create an **HttpRequest** object.
433. Call **httpRequest.on()** to subscribe to HTTP response header events. This API returns a response earlier than the request. You can subscribe to HTTP response header events based on service requirements.
444. Call **httpRequest.request()** to initiate a network request. You need to pass in the URL and optional parameters of the HTTP request.
455. Parse the returned result based on service requirements.
466. Call **off()** to unsubscribe from HTTP response header events.
477. Call **httpRequest.destroy()** to release resources after the request is processed.
48
49>**NOTE**
50>
51>In the sample code provided in this topic, **this.context** is used to obtain the UIAbilityContext, where **this** indicates a UIAbility instance inherited from **UIAbility**. To use **UIAbilityContext** APIs on pages, see [Obtaining the Context of UIAbility](../application-models/uiability-usage.md#obtaining-the-context-of-uiability).
52
53```ts
54// Import the http namespace.
55import { http } from '@kit.NetworkKit';
56import { BusinessError } from '@kit.BasicServicesKit';
57import { common } from '@kit.AbilityKit';
58
59let context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
60// Each httpRequest corresponds to an HTTP request task and cannot be reused.
61let httpRequest = http.createHttp();
62// This API is used to listen for the HTTP Response Header event, which is returned earlier than the result of the HTTP request. It is up to you whether to listen for HTTP Response Header events.
63// on('headerReceive', AsyncCallback) is replaced by on('headersReceive', Callback) since API version 8.
64httpRequest.on('headersReceive', (header) => {
65  console.info('header: ' + JSON.stringify(header));
66});
67httpRequest.request(
68  // Customize EXAMPLE_URL in extraData on your own. It is up to you whether to add parameters to the URL.
69  "EXAMPLE_URL",
70  {
71    method: http.RequestMethod.POST, // Optional. The default value is http.RequestMethod.GET.
72    // You can add header fields based on service requirements.
73    header: {
74      'Content-Type': 'application/json'
75    },
76    // This field is used to transfer the request body when a POST request is used. Its format needs to be negotiated with the server.
77    extraData: "data to send",
78    expectDataType: http.HttpDataType.STRING, // Optional. This field specifies the type of the return data.
79    usingCache: true, // Optional. The default value is true.
80    priority: 1, // Optional. The default value is 1.
81    connectTimeout: 60000 // Optional. The default value is 60000, in ms.
82    readTimeout: 60000, // Optional. The default value is 60000, in ms.
83    usingProtocol: http.HttpProtocol.HTTP1_1, // Optional. The default protocol type is automatically specified by the system.
84    usingProxy: false, // Optional. By default, network proxy is not used. This field is supported since API version 10.
85    caPath: '/path/to/cacert.pem', // Optional. The prebuilt CA certificate is used by default. This field is supported since API version 10.
86    clientCert: { // Optional. The client certificate is not used by default. This field is supported since API version 11.
87      certPath: '/path/to/client.pem', // The client certificate is not used by default. This field is supported since API version 11.
88      keyPath: '/path/to/client.key', // If the certificate contains key information, an empty string is passed. This field is supported since API version 11.
89      certType: http.CertType.PEM, // Certificate type, optional. A certificate in the PEM format is used by default. This field is supported since API version 11.
90      keyPassword: "passwordToKey" // Password of the key file, optional. It is supported since API version 11.
91    },
92    multiFormDataList: [ // Optional. This field is valid only when content-Type in the header is multipart/form-data. It is supported since API version 11.
93      {
94        name: "Part1", // Data name. This field is supported since API version 11.
95        contentType: 'text/plain', // Data type. This field is supported since API version 11.
96        data: 'Example data', // Data content, optional. This field is supported since API version 11.
97        remoteFileName: 'example.txt' // Optional. This field is supported since API version 11.
98      }, {
99        name: "Part2", // Data name. This field is supported since API version 11.
100        contentType: 'text/plain', // Data type. This field is supported since API version 11.
101        // data/app/el2/100/base/com.example.myapplication/haps/entry/files/fileName.txt
102        filePath: `${context.filesDir}/fileName.txt`, // File path, optional. This field is supported since API version 11.
103        remoteFileName: 'fileName.txt' // Optional. This field is supported since API version 11.
104      }
105    ]
106  }, (err: BusinessError, data: http.HttpResponse) => {
107    if (!err) {
108      // data.result carries the HTTP response. Parse the response based on service requirements.
109      console.info('Result:' + JSON.stringify(data.result));
110      console.info('code:' + JSON.stringify(data.responseCode));
111      // data.header carries the HTTP response header. Parse the content based on service requirements.
112      console.info('header:' + JSON.stringify(data.header));
113      console.info('cookies:' + JSON.stringify(data.cookies)); // 8+
114      // Call the destroy() method to release resources after HttpRequest is complete.
115      httpRequest.destroy();
116    } else {
117      console.error('error:' + JSON.stringify(err));
118      // Unsubscribe from HTTP Response Header events.
119      httpRequest.off('headersReceive');
120      // Call the destroy() method to release resources after HttpRequest is complete.
121      httpRequest.destroy();
122    }
123  }
124);
125```
126
127## Initiating an HTTP Streaming Request
128
1291. Import the **http** namespace from **@kit.NetworkKit**.
1302. Call **createHttp()** to create an **HttpRequest** object.
1313. Depending on your need, call **on()** of the **HttpRequest** object to subscribe to HTTP response header events as well as events indicating receiving of HTTP streaming responses, progress of receiving HTTP streaming responses, and completion of receiving HTTP streaming responses.
1324. Call **requestInStream()** to initiate a network request. You need to pass in the URL and optional parameters of the HTTP request.
1335. Parse the returned response code as needed.
1346. Call **off()** of the **HttpRequest** object to unsubscribe from the related events.
1357. Call **httpRequest.destroy()** to release resources after the request is processed.
136
137```ts
138// Import the http namespace.
139import { http } from '@kit.NetworkKit';
140import { BusinessError } from '@kit.BasicServicesKit';
141
142// Each httpRequest corresponds to an HTTP request task and cannot be reused.
143let httpRequest = http.createHttp();
144// Subscribe to HTTP response header events.
145httpRequest.on('headersReceive', (header: Object) => {
146  console.info('header: ' + JSON.stringify(header));
147});
148// Subscribe to events indicating receiving of HTTP streaming responses.
149let res = new ArrayBuffer(0);
150httpRequest.on('dataReceive', (data: ArrayBuffer) => {
151   const newRes = new ArrayBuffer(res.byteLength + data.byteLength);
152   const resView = new Uint8Array(newRes);
153   resView.set(new Uint8Array(res));
154   resView.set(new Uint8Array(data), res.byteLength);
155   res = newRes;
156   console.info('res length: ' + res.byteLength);
157});
158// Subscribe to events indicating completion of receiving HTTP streaming responses.
159httpRequest.on('dataEnd', () => {
160  console.info('No more data in response, data receive end');
161});
162// Subscribe to events indicating progress of receiving HTTP streaming responses.
163class Data {
164  receiveSize: number = 0;
165  totalSize: number = 0;
166}
167httpRequest.on('dataReceiveProgress', (data: Data) => {
168  console.log("dataReceiveProgress receiveSize:" + data.receiveSize + ", totalSize:" + data.totalSize);
169});
170
171let streamInfo: http.HttpRequestOptions = {
172  method: http.RequestMethod.POST, // Optional. The default value is http.RequestMethod.GET.
173  // You can add header fields based on service requirements.
174  header: {
175    'Content-Type': 'application/json'
176  },
177  // This field is used to transfer the request body when a POST request is used. Its format needs to be negotiated with the server.
178  extraData: "data to send",
179  expectDataType: http.HttpDataType.STRING, // Optional. This field specifies the type of the return data.
180  usingCache: true, // Optional. The default value is true.
181  priority: 1, // Optional. The default value is 1.
182  connectTimeout: 60000 // Optional. The default value is 60000, in ms.
183  readTimeout: 60000, // Optional. The default value is 60000, in ms. If a large amount of data needs to be transmitted, you are advised to set this parameter to a larger value to ensure normal data transmission.
184  usingProtocol: http.HttpProtocol.HTTP1_1 // Optional. The default protocol type is automatically specified by the system.
185}
186
187// Customize EXAMPLE_URL in extraData on your own. It is up to you whether to add parameters to the URL.
188httpRequest.requestInStream("EXAMPLE_URL", streamInfo).then((data: number) => {
189  console.info("requestInStream OK!");
190  console.info('ResponseCode :' + JSON.stringify(data));
191  // Unsubscribe from HTTP Response Header events.
192  httpRequest.off('headersReceive');
193  // Unregister the observer for events indicating receiving of HTTP streaming responses.
194  httpRequest.off('dataReceive');
195  // Unregister the observer for events indicating progress of receiving HTTP streaming responses.
196  httpRequest.off('dataReceiveProgress');
197  // Unregister the observer for events indicating completion of receiving HTTP streaming responses.
198  httpRequest.off('dataEnd');
199  // Call the destroy() method to release resources after HttpRequest is complete.
200  httpRequest.destroy();
201}).catch((err: Error) => {
202  console.info("requestInStream ERROR : err = " + JSON.stringify(err));
203});
204```
205
206## Certificate Pinning
207
208You can prebuild application-level certificates or a public key hash values for certificate pinning. This way, an HTTPS connection can be established only when the prebuilt certificate is used.
209
210Both modes are configured through `src/main/resources/base/profile/network_config.json`. In the configuration file, you can create mapping between prebuilt certificates and network servers.
211
212If you do not know the certificate mapping a server domain name, you can use the following command to obtain the certificate. When running the command, change `www.example.com` to the server domain name and `www.example.com.pem` to the name of the obtained certificate file.
213
214```
215openssl s_client -servername www.example.com -connect www.example.com:443 \
216    < /dev/null | sed -n "/-----BEGIN/,/-----END/p" > www.example.com.pem
217```
218
219If you are using a Windows environment, you need to:
220
221* Replace `/dev/null` with `NUL`.
222* Press **Enter** to exit. This is different from OpenSSL of Linux, which may exit until the user enters a value.
223* If the **sed** command is not present, copy the content between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----` (with these two lines included) in the command output and save it.
224
225### Prebuilding Application-level Certificates
226
227Prebuilding application-level certificates means to embed the original certificate files in the application. Currently, certificate files in the **.crt** and **.pem** formats are supported.
228
229> **NOTE**
230>
231> Currently, certificate pinning has been enabled for the ohos.net.http and Image components, and the hash values of all certificates in the certificate chain are matched. If any certificate is updated on the server, the verification fails. Therefore, if any certificate on the server has been updated, upgrade the application to the latest version as soon as possible. Otherwise, network connection may fail.
232
233### Prebuilding Certificate Public Key Hash Values
234
235You can create mapping between public key hash values and domain name certificates in the configuration file. This way, access to the domain name is allowed only if the used domain name certificate matches the prebuilt public key hash value.
236
237The public key hash value of the domain name certificate can be calculated using the following command. Assume that the domain name certificate is obtained using the preceding OpenSSL command and saved in the `www.example.com.pem` file. The line that starts with # is treated as a comment.
238
239```
240# Extract the public key from the certificate.
241openssl x509 -in www.example.com.pem -pubkey -noout > www.example.com.pubkey.pem
242# Convert the public key from the pem format to the der format.
243openssl asn1parse -noout -inform pem -in www.example.com.pubkey.pem -out www.example.com.pubkey.der
244# Calculate the SHA256 of the public key and convert it to Base64.
245openssl dgst -sha256 -binary www.example.com.pubkey.der | openssl base64
246```
247
248### Example of the JSON Configuration File
249
250The following is an example of prebuilt application-level certificates. For details about the configuration path, see [Network Connection Security Configuration](https://developer.huawei.com/consumer/en/doc/best-practices/bpta-network-ca-security#section5454123841911).
251
252```json
253{
254  "network-security-config": {
255    "base-config": {
256      "trust-anchors": [
257        {
258          "certificates": "/etc/security/certificates"
259        }
260      ]
261    },
262    "domain-config": [
263      {
264        "domains": [
265          {
266            "include-subdomains": true,
267            "name": "example.com"
268          }
269        ],
270        "trust-anchors": [
271          {
272            "certificates": "/data/storage/el1/bundle/entry/resources/resfile"
273          }
274        ]
275      }
276    ]
277  }
278}
279```
280
281The following is an example of prebuilt certificate public key hash values:
282```
283{
284  "network-security-config": {
285    "domain-config": [
286      {
287        "domains": [
288          {
289            "include-subdomains": true,
290            "name": "server.com"
291          }
292        ],
293        "pin-set": {
294          "expiration": "2024-11-08",
295          "pin": [
296            {
297              "digest-algorithm": "sha256",
298              "digest": "FEDCBA987654321"
299            }
300          ]
301        }
302      }
303    ]
304  }
305}
306```
307
308The following is an example configuration for overall and host name–based HTTP access:
309```
310{
311  "network-security-config": {
312    "base-config": {
313      "cleartextTrafficPermitted": true
314    },
315    "domain-config": [
316      {
317        "domains": [
318          {
319            "include-subdomains": true,
320            "name": "example.com"
321          }
322        ],
323        "cleartextTrafficPermitted": false
324      }
325    ]
326  }
327}
328```
329
330The following is an example configuration of the certificate pin:
331```
332{
333  "network-security-config": {
334    "domain-config": [
335      {
336        "domains": [
337          {
338            "include-subdomains": true,
339            "name": "server.com"
340          }
341        ],
342        "pin-set": {
343          "expiration": "2024-11-08",
344          "pin": [
345            {
346              "digest-algorithm": "sha256",
347              "digest": "FEDCBA987654321"
348            }
349          ]
350        }
351      }
352    ]
353  },
354  "trust-global-user-ca": false,
355  "trust-current-user-ca": false,
356}
357```
358
359**Description of fields**
360
361| Field                     | Type           | Description                                  |
362| --------------------------| --------------- | -------------------------------------- |
363|network-security-config    | object          |Network security configuration. The value can contain zero or one **base-config** and must contain one **domain-config**.|
364|base-config                | object          |Application security configuration. The value must contain one **trust-anchors**.                         |
365|domain-config              | array           |Domain security configuration. The value can contain any number of items. An item must contain one **domains** and can contain zero or one **trust-anchors** and **pin-set**.|
366|trust-anchors              | array           |Trusted CA. The value can contain any number of items. An item must contain one **certificates**.|
367|certificates               | string          |CA certificate path.|
368|domains                    | array           |Domain. The value can contain any number of items. An item must contain one **name** (string: domain name) and can contain zero or one **include-subdomains**.|
369|include-subdomains         | boolean         |Whether a rule applies to subdomains. Whether a rule applies to subdomains. The value **true** indicates that the rule applies to subdomains, and the value **false** indicates the opposite.|
370|pin-set                    | object          |Certificate public key hash setting. The value must contain one **pin** and can contain zero or one **expiration**.|
371|expiration                 | string          |Expiration time of the certificate public key hash.|
372|pin                        | array           |Certificate public key hash. The value can contain any number of items. An item must contain one **digest-algorithm** and **digest**.|
373|digest-algorithm           | string          |Digest algorithm used to generate hashes. Currently, only `sha256` is supported.                                   |
374|digest                     | string          |Public key hash.|
375|cleartextTrafficPermitted  | boolean          |Whether plaintext HTTP is allowed. The value **true** indicates that plaintext HTTP is allowed, and the value **false** indicates the opposite.|
376
377
378## Configuring Untrusted User-Installed CA Certificates
379By default, the system trusts the prebuilt CA certificates and user-installed CA certificates. To further improve security, you can configure untrusted user-installed CA certificates in **src/main/resources/base/profile/network_config.json**. For more network connection security configurations, see [Network Connection Security Configuration](https://developer.huawei.com/consumer/en/doc/best-practices/bpta-network-ca-security#section5454123841911).
380```
381{
382  "network-security-config": {
383    ... ...
384  },
385  "trust-global-user-ca": false, // Set whether to trust the CA certificate manually installed by the enterprise MDM system or device administrator. The default value is true.
386  "trust-current-user-ca" : false // Set whether to trust the certificate installed by the current user. The default value is true.
387}
388```
389