1. HttpRequest模擬登錄簡(jiǎn)介
在本系列的第9篇文章《鴻蒙網(wǎng)絡(luò)編程系列9-使用HttpRequest模擬登錄示例》中,我們基于ArkTS語(yǔ)言在API 9的環(huán)境下使用HttpRequest發(fā)起HTTP請(qǐng)求,模擬了對(duì)目標(biāo)網(wǎng)站的登錄,本文將使用倉(cāng)頡語(yǔ)言在API 12的環(huán)境中實(shí)現(xiàn)類似的功能。
鴻蒙封裝的HTTP操作類位于模塊http中,使用如下的方式導(dǎo)入:
import ohos.net.http.*
http模塊包括多個(gè)http請(qǐng)求相關(guān)函數(shù),就本文而言,重點(diǎn)需要掌握的是如下兩個(gè):
//創(chuàng)建一個(gè)HTTP請(qǐng)求,每一個(gè)HttpRequest對(duì)象對(duì)應(yīng)一個(gè)HTTP請(qǐng)求,如需發(fā)起多個(gè)HTTP請(qǐng)求,須為每個(gè)請(qǐng)求創(chuàng)建對(duì)應(yīng)對(duì)象。
1. public func createHttp(): HttpRequest
//根據(jù)URL地址,發(fā)起HTTP網(wǎng)絡(luò)請(qǐng)求,在callback回調(diào)函數(shù)中返回響應(yīng)。
2. public func request(url: String, callback: (?BusinessException, ?HttpResponse) -> Unit, options!: ?HttpRequestOptions = None): Unit
2. HttpRequest模擬登錄演示
為演示HTTP模擬登錄,假設(shè)我們有這樣一個(gè)網(wǎng)站,訪問該網(wǎng)站時(shí)如果沒有登錄,會(huì)被重定向到登錄頁(yè)面,如圖所示:

輸入用戶名和密碼,單擊“登錄”按鈕即可完成登錄,返回首頁(yè),如圖所示:

我們要實(shí)現(xiàn)的示例就是模擬這個(gè)登錄過程,從而可以得到首頁(yè)登錄后的內(nèi)容。
本示例運(yùn)行后的頁(yè)面如圖所示:

輸入要登錄的網(wǎng)址和用戶名、密碼,然后單擊“登錄”按鈕進(jìn)行登錄,應(yīng)用會(huì)發(fā)起HTTP請(qǐng)求并返回響應(yīng)內(nèi)容,如圖所示:

可以看到已經(jīng)成功登錄了。
3. HttpRequest模擬登錄示例編寫
下面詳細(xì)介紹創(chuàng)建該示例的步驟(確保DevEco Studio已安裝倉(cāng)頡插件)。
步驟1:創(chuàng)建[Cangjie]Empty Ability項(xiàng)目。
步驟2:在module.json5配置文件加上對(duì)權(quán)限的聲明:
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
這里添加了訪問互聯(lián)網(wǎng)的權(quán)限。
步驟3:在build-profile.json5配置文件加上倉(cāng)頡編譯架構(gòu):
"cangjieOptions": {
"path": "./src/main/cangjie/cjpm.toml",
"abiFilters": ["arm64-v8a", "x86_64"]
}
步驟4:在index.cj文件里添加如下的代碼:
package ohos_app_cangjie_entry
internal import ohos.base.LengthProp
internal import ohos.component.Column
internal import ohos.component.Row
internal import ohos.component.Button
internal import ohos.component.Text
internal import ohos.component.CustomView
internal import ohos.component.CJEntry
internal import ohos.component.loadNativeView
import ohos.base.*
import ohos.component.*
import ohos.state_manage.*
import ohos.state_macro_manage.*
import std.collection.HashMap
import ohos.net.http.*
@Entry
@Component
class EntryView {
//連接、通訊歷史記錄
@State
var msgHistory: String = ''
//登錄地址
@State
var loginUrl: String = "http://*.*.*.*:8081/auth"
//用戶名
@State
var loginName: String = "zhanglei"
//密碼
@State
var passwd: String = "HarmonyOS"
let scroller: Scroller = Scroller()
func build() {
Row {
Column {
Text("模擬登錄示例").fontSize(14).fontWeight(FontWeight.Bold).width(100.percent).textAlign(
TextAlign.Center).padding(10)
Flex(FlexParams(justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center)) {
Text("用戶名:").fontSize(14)
TextInput(text: loginName).onChange({
value => loginName = value
}).width(100).fontSize(11).flexGrow(1)
Text("密碼:").fontSize(14)
TextInput(text: passwd).onChange({
value => passwd = value
}).width(100).fontSize(11).setType(InputType.Password).flexGrow(1)
}.width(100.percent).padding(10)
Flex(FlexParams(justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center)) {
Text("登錄地址:").fontSize(14).width(80)
TextInput(text: loginUrl).onChange({
value => loginUrl = value
}).width(100).fontSize(11).flexGrow(1)
Button("登錄").onClick {
evt => login()
}.width(70).fontSize(14).flexGrow(0)
}.width(100.percent).padding(10)
Scroll(scroller) {
Text(msgHistory).textAlign(TextAlign.Start).padding(10).width(100.percent).backgroundColor(0xeeeeee)
}.align(Alignment.Top).backgroundColor(0xeeeeee).height(300).flexGrow(1).scrollable(
ScrollDirection.Vertical).scrollBar(BarState.On).scrollBarWidth(20)
}.width(100.percent).height(100.percent)
}.height(100.percent)
}
//登錄
func login() {
//http請(qǐng)求對(duì)象
let httpRequest = createHttp();
//請(qǐng)求的登錄名和密碼參數(shù)
let params = "username=" + loginName + "&password=" + passwd
let header = HashMap<String, String>(("Content-Type", "application/x-www-form-urlencoded"));
let opt = HttpRequestOptions(
method: RequestMethod.POST,
extraData: HttpData.STRING_DATA(params),
header: header,
expectDataType: HttpDataType.STRING
)
httpRequest.request(loginUrl, dealWithResponse, options: opt)
}
//發(fā)起http請(qǐng)求后的回調(diào)函數(shù)
func dealWithResponse(err: ?BusinessException, response: ?HttpResponse) {
if (let Some(e) <- err) {
msgHistory += "請(qǐng)求失?。? + e.message + "\r\n"
}
if (let Some(resp) <- response) {
msgHistory += "響應(yīng)碼:${resp.responseCode.getValue()}\r\n"
msgHistory += resp.result.toString() + "\r\n"
} else {
msgHistory += "響應(yīng)為空\(chéng)r\n"
}
}
}
步驟5:編譯運(yùn)行,可以使用模擬器或者真機(jī)。
步驟6:按照本節(jié)第2部分“HttpRequest模擬登錄演示”操作即可。
4. 代碼分析
本示例比較簡(jiǎn)單,關(guān)鍵點(diǎn)在于構(gòu)造HTTP請(qǐng)求的參數(shù)以及請(qǐng)求響應(yīng)后的處理,這里通過HttpRequestOptions類型封裝了請(qǐng)求參數(shù),包括請(qǐng)求體以及header部分的內(nèi)容:
let params = "username=" + loginName + "&password=" + passwd
let header = HashMap<String, String>(("Content-Type", "application/x-www-form-urlencoded"));
let opt = HttpRequestOptions(
method: RequestMethod.POST,
extraData: HttpData.STRING_DATA(params),
header: header,
expectDataType: HttpDataType.STRING
)
另外需要注意的是,倉(cāng)頡語(yǔ)言對(duì)類似Null值的處理是通過Some語(yǔ)法來判斷的,這一點(diǎn)和ArkTS以及其他語(yǔ)言有較大的區(qū)別。
(本文作者原創(chuàng),除非明確授權(quán)禁止轉(zhuǎn)載)
本文源碼地址:
https://gitee.com/zl3624/harmonyos_network_samples/tree/master/code/http/HttpSimulateLogin4Cj