黄sir要先给大家泼一盆冷水
面试官问你:「鸿蒙里怎么发网络请求?」
你脱口而出:「用 http 模块啊!」
面试官点点头:「那你封装过吗?」
你:「……」
http 请求封装,是鸿蒙面试的标配问题。 不是什么高深架构,但能直接反映出你对 ArkTS 的理解深度。
今天黄sir手把手教你写一套能直接拿来用的网络请求封装,代码不多,但每一行都有讲究。
1. 先搞清楚依赖
在 entry 的 module.json5 里加上:
{ "module": { "requests": [ { "abilities": [ { "permissions": [ "ohos.permission.INTERNET" ] } ] } ] }}
没加这个 Permission?那你发请求的时候会得到一个 code 201 报错,调试半天找不到原因。2. 基础请求方法
import http from '@ohos.net.http'export function request(url: string, options: http.HttpRequestOptions): Promise<any> { return new Promise((resolve, reject) => { let httpRequest = http.createHttp() httpRequest.request(url, { method: options.method || 'GET', header: options.header || {}, extraData: options.data || {} }, (err, data) => { if (err) { reject(err) return } if (data.responseCode === 200) { resolve(JSON.parse(data.result as string)) } else { reject({ code: data.responseCode, msg: '请求失败' }) } httpRequest.destroy() }) })}
3. 加上拦截器(,这才是区分水平的地方)
光有基础请求还不够,实际项目里你需要:
class HttpClient { private baseUrl: string = 'https://api.example.com' private token: string = '' setToken(token: string) { this.token = token } async get(path: string, params?: object): Promise<any> { let url = this.baseUrl + path if (params) { url += '?' + Object.entries(params).map(([k, v]) => `${k}=${v}`).join('&') } return this.request(url, { method: 'GET' }) } async post(path: string, data: object): Promise<any> { return this.request(this.baseUrl + path, { method: 'POST', header: { 'Content-Type': 'application/json' }, data: JSON.stringify(data) }) } private request(url: string, options: http.HttpRequestOptions): Promise<any> { return new Promise((resolve, reject) => { let httpRequest = http.createHttp() // 统一加token let headers = options.header || {} if (this.token) { headers['Authorization'] = `Bearer ${this.token}` } options.header = headers httpRequest.request(url, options, (err, data) => { if (err) { reject(err) httpRequest.destroy() return } if (data.responseCode === 200) { resolve(JSON.parse(data.result as string)) } else { reject({ code: data.responseCode, msg: '接口异常' }) } httpRequest.destroy() }) }) }}export const httpClient = new HttpClient()
// 登录const res = await httpClient.post('/login', { username: 'lusi', password: '123' })httpClient.setToken(res.data.token)// 后续请求自动带tokenconst userInfo = await httpClient.get('/user/info')
4. 常见的坑
坑1:数据解析报错
// ❌ 错误:result可能是空字符串JSON.parse(data.result)// ✅ 正确:先判断const result = data.result as stringif (result) { resolve(JSON.parse(result))}
// 超时配置(单位毫秒)httpRequest.request(url, { ... connectTimeout: 10000, readTimeout: 10000})
HTTP 协议里 header 是大小写不敏感的,但部分服务端做了校验。建议统一用小写:content-type → Content-Type。黄sir的忠告
网络请求封装这个东西,看着简单,水很深。
面试的时候,你能说清楚为什么用 Promise、为什么每次请求要 destroy、token 怎么统一注入——这说明你真正理解了。
只会调 http.createHttp() 的,叫初级工程师。 能把拦截器、鉴权、异常处理说清楚的,叫中级工程师。
你想做哪个?
📦 福利时间
💬 你在封装网络请求的时候踩过什么坑?
评论区聊聊,黄sir选几个典型问题下篇文章详细讲。