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## Available APIs 8 9The HTTP request function is mainly implemented by the HTTP module. 10 11To use related APIs, you must declare the **ohos.permission.INTERNET** permission. 12 13For details about how to apply for permissions, see [Declaring Permissions](../security/AccessToken/declare-permissions.md). 14 15The following table provides only a simple description of the related APIs. For details, see [API Reference](../reference/apis-network-kit/js-apis-http.md). 16 17| API | Description | 18| ----------------------------------------- | ----------------------------------- | 19| createHttp() | Creates an HTTP request. | 20| request() | Initiates an HTTP request to a given URL. | 21| requestInStream()<sup>10+</sup> | Initiates an HTTP network request to a given URL and returns a streaming response.| 22| destroy() | Destroys an HTTP request. | 23| on(type: 'headersReceive') | Registers an observer for HTTP Response Header events. | 24| off(type: 'headersReceive') | Unregisters the observer for HTTP Response Header events.| 25| once\('headersReceive'\)<sup>8+</sup> | Registers a one-time observer for HTTP Response Header events.| 26| on\('dataReceive'\)<sup>10+</sup> | Registers an observer for events indicating receiving of HTTP streaming responses. | 27| off\('dataReceive'\)<sup>10+</sup> | Unregisters the observer for events indicating receiving of HTTP streaming responses. | 28| on\('dataEnd'\)<sup>10+</sup> | Registers an observer for events indicating completion of receiving HTTP streaming responses. | 29| off\('dataEnd'\)<sup>10+</sup> | Unregisters the observer for events indicating completion of receiving HTTP streaming responses.| 30| on\('dataReceiveProgress'\)<sup>10+</sup> | Registers an observer for events indicating progress of receiving HTTP streaming responses. | 31| off\('dataReceiveProgress'\)<sup>10+</sup> | Unregisters the observer for events indicating progress of receiving HTTP streaming responses.| 32| on\('dataSendProgress'\)<sup>11+</sup> | Registers an observer for events indicating progress of sending HTTP requests. | 33| off\('dataSendProgress'\)<sup>11+</sup> | Unregisters the observer for events indicating progress of sending HTTP requests.| 34 35## How to Develop request APIs 36 371. Import the **http** namespace from **@kit.NetworkKit**. 382. Call **createHttp()** to create an **HttpRequest** object. 393. 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. 404. Call **httpRequest.request()** to initiate a network request. You need to pass in the URL and optional parameters of the HTTP request. 415. Parse the returned result based on service requirements. 426. Call **off()** to unsubscribe from HTTP response header events. 437. Call **httpRequest.destroy()** to release resources after the request is processed. 44 45```ts 46// Import the http namespace. 47import { http } from '@kit.NetworkKit'; 48import { BusinessError } from '@kit.BasicServicesKit'; 49 50// Each httpRequest corresponds to an HTTP request task and cannot be reused. 51let httpRequest = http.createHttp(); 52// 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. 53// on('headerReceive', AsyncCallback) is replaced by on('headersReceive', Callback) since API version 8. 54httpRequest.on('headersReceive', (header) => { 55 console.info('header: ' + JSON.stringify(header)); 56}); 57httpRequest.request( 58 // Customize EXAMPLE_URL in extraData on your own. It is up to you whether to add parameters to the URL. 59 "EXAMPLE_URL", 60 { 61 method: http.RequestMethod.POST, // Optional. The default value is http.RequestMethod.GET. 62 // You can add header fields based on service requirements. 63 header: { 64 'Content-Type': 'application/json' 65 }, 66 // This field is used to transfer the request body when a POST request is used. Its format needs to be negotiated with the server. 67 extraData: "data to send", 68 expectDataType: http.HttpDataType.STRING, // Optional. This field specifies the type of the return data. 69 usingCache: true, // Optional. The default value is true. 70 priority: 1, // Optional. The default value is 1. 71 connectTimeout: 60000 // Optional. The default value is 60000, in ms. 72 readTimeout: 60000, // Optional. The default value is 60000, in ms. 73 usingProtocol: http.HttpProtocol.HTTP1_1, // Optional. The default protocol type is automatically specified by the system. 74 usingProxy: false, // Optional. By default, network proxy is not used. This field is supported since API version 10. 75 caPath: '/path/to/cacert.pem', // Optional. The preset CA certificate is used by default. This field is supported since API version 10. 76 clientCert: { // Optional. The client certificate is not used by default. This field is supported since API version 11. 77 certPath: '/path/to/client.pem', // The client certificate is not used by default. This field is supported since API version 11. 78 keyPath: '/path/to/client.key', // If the certificate contains key information, an empty string is passed. This field is supported since API version 11. 79 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. 80 keyPassword: "passwordToKey" // Password of the key file, optional. It is supported since API version 11. 81 }, 82 multiFormDataList: [ // Optional. This field is valid only when content-Type in the header is multipart/form-data. It is supported since API version 11. 83 { 84 name: "Part1", // Data name. This field is supported since API version 11. 85 contentType: 'text/plain', // Data type. This field is supported since API version 11. 86 data: 'Example data', // Data content, optional. This field is supported since API version 11. 87 remoteFileName: 'example.txt' // Optional. This field is supported since API version 11. 88 }, { 89 name: "Part2", // Data name. This field is supported since API version 11. 90 contentType: 'text/plain', // Data type. This field is supported since API version 11. 91 // data/app/el2/100/base/com.example.myapplication/haps/entry/files/fileName.txt 92 filePath: `${getContext(this).filesDir}/fileName.txt`, // File path, optional. This field is supported since API version 11. 93 remoteFileName: 'fileName.txt' // Optional. This field is supported since API version 11. 94 } 95 ] 96 }, (err: BusinessError, data: http.HttpResponse) => { 97 if (!err) { 98 // data.result carries the HTTP response. Parse the response based on service requirements. 99 console.info('Result:' + JSON.stringify(data.result)); 100 console.info('code:' + JSON.stringify(data.responseCode)); 101 // data.header carries the HTTP response header. Parse the content based on service requirements. 102 console.info('header:' + JSON.stringify(data.header)); 103 console.info('cookies:' + JSON.stringify(data.cookies)); // 8+ 104 // Call the destroy() method to release resources after HttpRequest is complete. 105 httpRequest.destroy(); 106 } else { 107 console.error('error:' + JSON.stringify(err)); 108 // Unsubscribe from HTTP Response Header events. 109 httpRequest.off('headersReceive'); 110 // Call the destroy() method to release resources after HttpRequest is complete. 111 httpRequest.destroy(); 112 } 113 } 114); 115``` 116 117## How to Develop requestInStream APIs 118 1191. Import the **http** namespace from **@kit.NetworkKit**. 1202. Call **createHttp()** to create an **HttpRequest** object. 1213. 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. 1224. Call **requestInStream()** to initiate a network request. You need to pass in the URL and optional parameters of the HTTP request. 1235. Parse the returned response code as needed. 1246. Call **off()** of the **HttpRequest** object to unsubscribe from the related events. 1257. Call **httpRequest.destroy()** to release resources after the request is processed. 126 127```ts 128// Import the http namespace. 129import { http } from '@kit.NetworkKit'; 130import { BusinessError } from '@kit.BasicServicesKit'; 131 132// Each httpRequest corresponds to an HTTP request task and cannot be reused. 133let httpRequest = http.createHttp(); 134// Subscribe to HTTP response header events. 135httpRequest.on('headersReceive', (header: Object) => { 136 console.info('header: ' + JSON.stringify(header)); 137}); 138// Subscribe to events indicating receiving of HTTP streaming responses. 139let res = new ArrayBuffer(0); 140httpRequest.on('dataReceive', (data: ArrayBuffer) => { 141 const newRes = new ArrayBuffer(res.byteLength + data.byteLength); 142 const resView = new Uint8Array(newRes); 143 resView.set(new Uint8Array(res)); 144 resView.set(new Uint8Array(data), res.byteLength); 145 res = newRes; 146 console.info('res length: ' + res.byteLength); 147}); 148// Subscribe to events indicating completion of receiving HTTP streaming responses. 149httpRequest.on('dataEnd', () => { 150 console.info('No more data in response, data receive end'); 151}); 152// Subscribe to events indicating progress of receiving HTTP streaming responses. 153class Data { 154 receiveSize: number = 0; 155 totalSize: number = 0; 156} 157httpRequest.on('dataReceiveProgress', (data: Data) => { 158 console.log("dataReceiveProgress receiveSize:" + data.receiveSize + ", totalSize:" + data.totalSize); 159}); 160 161let streamInfo: http.HttpRequestOptions = { 162 method: http.RequestMethod.POST, // Optional. The default value is http.RequestMethod.GET. 163 // You can add header fields based on service requirements. 164 header: { 165 'Content-Type': 'application/json' 166 }, 167 // This field is used to transfer the request body when a POST request is used. Its format needs to be negotiated with the server. 168 extraData: "data to send", 169 expectDataType: http.HttpDataType.STRING, // Optional. This field specifies the type of the return data. 170 usingCache: true, // Optional. The default value is true. 171 priority: 1, // Optional. The default value is 1. 172 connectTimeout: 60000 // Optional. The default value is 60000, in ms. 173 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. 174 usingProtocol: http.HttpProtocol.HTTP1_1 // Optional. The default protocol type is automatically specified by the system. 175} 176 177// Customize EXAMPLE_URL in extraData on your own. It is up to you whether to add parameters to the URL. 178httpRequest.requestInStream("EXAMPLE_URL", streamInfo).then((data: number) => { 179 console.info("requestInStream OK!"); 180 console.info('ResponseCode :' + JSON.stringify(data)); 181 // Unsubscribe from HTTP Response Header events. 182 httpRequest.off('headersReceive'); 183 // Unregister the observer for events indicating receiving of HTTP streaming responses. 184 httpRequest.off('dataReceive'); 185 // Unregister the observer for events indicating progress of receiving HTTP streaming responses. 186 httpRequest.off('dataReceiveProgress'); 187 // Unregister the observer for events indicating completion of receiving HTTP streaming responses. 188 httpRequest.off('dataEnd'); 189 // Call the destroy() method to release resources after HttpRequest is complete. 190 httpRequest.destroy(); 191}).catch((err: Error) => { 192 console.info("requestInStream ERROR : err = " + JSON.stringify(err)); 193}); 194``` 195 196## Certificate Pinning 197 198You can preset application-level certificates or a public key hash values for certificate pinning. This way, an HTTPS connection can be established only when the preset certificate is used. 199 200Both modes are configured in the configuration file, which is available at `src/main/resources/base/profile/network_config.json`. In the configuration file, you can create mapping between preset certificates and network servers. 201 202If 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. 203 204``` 205openssl s_client -servername www.example.com -connect www.example.com:443 \ 206 < /dev/null | sed -n "/-----BEGIN/,/-----END/p" > www.example.com.pem 207``` 208 209If you are using a Windows environment, you need to: 210 211* Replace `/dev/null` with `NUL`. 212* Press **Enter** to exit. This is different from OpenSSL of Linux, which may exit until the user enters a value. 213* 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. 214 215### Presetting Application-level Certificates 216 217Presetting application-level certificates means to embed the original certificate files in the application. Currently, certificate files in the **.crt** and **.pem** formats are supported. 218 219> **NOTE** 220> 221> 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. 222 223### Presetting Certificate Public Key Hash Values 224 225You 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 preset public key hash value. 226 227The 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. 228 229``` 230# Extract the public key from the certificate. 231openssl x509 -in www.example.com.pem -pubkey -noout > www.example.com.pubkey.pem 232# Convert the public key from the pem format to the der format. 233openssl asn1parse -noout -inform pem -in www.example.com.pubkey.pem -out www.example.com.pubkey.der 234# Calculate the SHA256 of the public key and convert it to Base64. 235openssl dgst -sha256 -binary www.example.com.pubkey.der | openssl base64 236``` 237 238### Example of the JSON Configuration File 239 240The following is an example of presetting application-level certificates: 241 242```json 243{ 244 "network-security-config": { 245 "base-config": { 246 "trust-anchors": [ 247 { 248 "certificates": "/etc/security/certificates" 249 } 250 ] 251 }, 252 "domain-config": [ 253 { 254 "domains": [ 255 { 256 "include-subdomains": true, 257 "name": "example.com" 258 } 259 ], 260 "trust-anchors": [ 261 { 262 "certificates": "/data/storage/el1/bundle/entry/resources/resfile" 263 } 264 ] 265 } 266 ] 267 } 268} 269``` 270 271The following is an example of presetting certificate public key hash values: 272``` 273{ 274 "network-security-config": { 275 "domain-config": [ 276 { 277 "domains": [ 278 { 279 "include-subdomains": true, 280 "name": "server.com" 281 } 282 ], 283 "pin-set": { 284 "expiration": "2024-11-08", 285 "pin": [ 286 { 287 "digest-algorithm": "sha256", 288 "digest": "FEDCBA987654321" 289 } 290 ] 291 } 292 } 293 ] 294 } 295} 296``` 297 298**Description of fields** 299 300| Field | Type | Description | 301| --------------------------| --------------- | -------------------------------------- | 302|network-security-config | object |Network security configuration. The value can contain zero or one **base-config** and must contain one **domain-config**.| 303|base-config | object |Application security configuration. The value must contain one **trust-anchors**. | 304|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**.| 305|trust-anchors | array |Trusted CA. The value can contain any number of items. An item must contain one **certificates**.| 306|certificates | string |CA certificate path.| 307|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**.| 308|include-subdomains | boolean |Whether a rule applies to subdomains.| 309|pin-set | object |Certificate public key hash setting. The value must contain one **pin** and can contain zero or one **expiration**.| 310|expiration | string |Expiration time of the certificate public key hash.| 311|pin | array |Certificate public key hash. The value can contain any number of items. An item must contain one **digest-algorithm** and **digest**.| 312|digest-algorithm | string |Digest algorithm used to generate hashes. Currently, only `sha256` is supported. | 313|digest | string |Public key hash.| 314 315 316