学校网站建设开发项目计划报告,外链查询网站,无锡滨湖住房与城乡建设局网站,四川省住建厅考试报名官网Harmony之路#xff1a;网络请求——HTTP模块与数据交互
一、引入#xff1a;为什么需要网络请求#xff1f;
在现代移动应用中#xff0c;几乎所有的应用都需要与服务器进行数据交互#xff0c;无论是获取新闻列表、用户登录、上传图片还是同步数据#xff0c;都离不开网…Harmony之路网络请求——HTTP模块与数据交互一、引入为什么需要网络请求在现代移动应用中几乎所有的应用都需要与服务器进行数据交互无论是获取新闻列表、用户登录、上传图片还是同步数据都离不开网络请求。HarmonyOS提供了HTTP模块作为网络请求的核心能力支持GET、POST、PUT、DELETE等多种HTTP方法能够满足各种网络通信需求。掌握HTTP模块的使用是构建完整应用的必要技能。二、讲解HTTP模块的核心用法1. HTTP模块基础配置在使用HTTP模块前需要先在应用的配置文件中声明网络权限。config.json权限配置{ module: { requestPermissions: [ { name: ohos.permission.INTERNET } ] } }2. 创建HTTP请求创建HTTP请求示例import http from ohos.net.http; // 创建HTTP请求对象 const httpRequest http.createHttp(); // 设置请求超时时间可选 httpRequest.setTimeout(10000); // 10秒超时3. GET请求GET请求用于从服务器获取数据是最常用的请求方法。GET请求示例import http from ohos.net.http; Entry Component struct GetExample { State data: string ; async fetchData() { try { const httpRequest http.createHttp(); // 发起GET请求 const response await httpRequest.request( https://jsonplaceholder.typicode.com/posts/1, { method: http.RequestMethod.GET, header: { Content-Type: application/json } } ); // 检查响应状态 if (response.responseCode 200) { const result JSON.parse(response.result); this.data JSON.stringify(result, null, 2); console.log(请求成功:, result); } else { console.error(请求失败:, response.responseCode); this.data 请求失败: ${response.responseCode}; } } catch (error) { console.error(请求异常:, error); this.data 请求异常: ${error.message}; } } build() { Column({ space: 20 }) { Button(发起GET请求) .onClick(() { this.fetchData(); }) Text(this.data) .fontSize(14) .textAlign(TextAlign.Start) .width(90%) .height(300) .border({ width: 1, color: Color.Gray }) } .width(100%) .height(100%) .justifyContent(FlexAlign.Center) } }4. POST请求POST请求用于向服务器提交数据常用于创建资源或提交表单。POST请求示例import http from ohos.net.http; Entry Component struct PostExample { State result: string ; async submitData() { try { const httpRequest http.createHttp(); // 请求数据 const requestData { title: foo, body: bar, userId: 1 }; // 发起POST请求 const response await httpRequest.request( https://jsonplaceholder.typicode.com/posts, { method: http.RequestMethod.POST, header: { Content-Type: application/json }, extraData: JSON.stringify(requestData) } ); if (response.responseCode 201) { const result JSON.parse(response.result); this.result JSON.stringify(result, null, 2); console.log(创建成功:, result); } else { console.error(创建失败:, response.responseCode); this.result 创建失败: ${response.responseCode}; } } catch (error) { console.error(请求异常:, error); this.result 请求异常: ${error.message}; } } build() { Column({ space: 20 }) { Button(发起POST请求) .onClick(() { this.submitData(); }) Text(this.result) .fontSize(14) .textAlign(TextAlign.Start) .width(90%) .height(300) .border({ width: 1, color: Color.Gray }) } .width(100%) .height(100%) .justifyContent(FlexAlign.Center) } }5. PUT和DELETE请求PUT用于更新资源DELETE用于删除资源。PUT和DELETE请求示例import http from ohos.net.http; class ApiService { private httpRequest: http.HttpRequest; constructor() { this.httpRequest http.createHttp(); } // 更新资源 async updatePost(id: number, data: any) { try { const response await this.httpRequest.request( https://jsonplaceholder.typicode.com/posts/${id}, { method: http.RequestMethod.PUT, header: { Content-Type: application/json }, extraData: JSON.stringify(data) } ); if (response.responseCode 200) { return JSON.parse(response.result); } else { throw new Error(更新失败: ${response.responseCode}); } } catch (error) { throw error; } } // 删除资源 async deletePost(id: number) { try { const response await this.httpRequest.request( https://jsonplaceholder.typicode.com/posts/${id}, { method: http.RequestMethod.DELETE } ); if (response.responseCode 200) { return { success: true }; } else { throw new Error(删除失败: ${response.responseCode}); } } catch (error) { throw error; } } }6. 请求头设置设置请求头可以传递认证信息、内容类型等。请求头设置示例import http from ohos.net.http; async function requestWithHeaders() { const httpRequest http.createHttp(); const response await httpRequest.request( https://api.example.com/data, { method: http.RequestMethod.GET, header: { Content-Type: application/json, Authorization: Bearer your-token-here, User-Agent: MyApp/1.0, Accept: application/json } } ); return response; }7. 请求参数GET请求可以通过URL参数传递数据POST请求可以通过extraData传递数据。URL参数示例import http from ohos.net.http; async function requestWithParams() { const httpRequest http.createHttp(); // 构建带参数的URL const params new URLSearchParams({ page: 1, limit: 10, sort: desc }); const url https://api.example.com/posts?${params.toString()}; const response await httpRequest.request( url, { method: http.RequestMethod.GET, header: { Content-Type: application/json } } ); return response; }8. 文件上传使用FormData格式上传文件。文件上传示例import http from ohos.net.http; import fileio from ohos.fileio; async function uploadFile(filePath: string) { const httpRequest http.createHttp(); // 读取文件内容 const fileContent await fileio.readText(filePath); // 构建FormData简化版实际需要更复杂的处理 const formData ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; namefile; filenametest.txt Content-Type: text/plain ${fileContent} ------WebKitFormBoundary7MA4YWxkTrZu0gW--; const response await httpRequest.request( https://api.example.com/upload, { method: http.RequestMethod.POST, header: { Content-Type: multipart/form-data; boundary----WebKitFormBoundary7MA4YWxkTrZu0gW }, extraData: formData } ); return response; }9. 实际应用场景场景1用户登录import http from ohos.net.http; import preferences from ohos.data.preferences; class AuthService { private httpRequest: http.HttpRequest; private preferences: preferences.Preferences; constructor(context: common.UIAbilityContext) { this.httpRequest http.createHttp(); this.preferences preferences.getPreferencesSync(context, authData); } async login(username: string, password: string): Promiseboolean { try { const response await this.httpRequest.request( https://api.example.com/auth/login, { method: http.RequestMethod.POST, header: { Content-Type: application/json }, extraData: JSON.stringify({ username, password }) } ); if (response.responseCode 200) { const result JSON.parse(response.result); // 保存token和用户信息 await this.preferences.put(token, result.token); await this.preferences.put(userInfo, JSON.stringify(result.user)); return true; } else { throw new Error(登录失败); } } catch (error) { console.error(登录异常:, error); return false; } } async logout() { try { const token await this.preferences.get(token, ); if (token) { await this.httpRequest.request( https://api.example.com/auth/logout, { method: http.RequestMethod.POST, header: { Authorization: Bearer ${token} } } ); } // 清除本地数据 await this.preferences.delete(token); await this.preferences.delete(userInfo); } catch (error) { console.error(退出登录异常:, error); } } async getToken(): Promisestring { return await this.preferences.get(token, ); } }场景2获取列表数据import http from ohos.net.http; class DataService { private httpRequest: http.HttpRequest; constructor() { this.httpRequest http.createHttp(); } async getPosts(page: number 1, limit: number 10): Promiseany[] { try { const params new URLSearchParams({ page: page.toString(), limit: limit.toString() }); const url https://jsonplaceholder.typicode.com/posts?${params.toString()}; const response await this.httpRequest.request( url, { method: http.RequestMethod.GET, header: { Content-Type: application/json } } ); if (response.responseCode 200) { return JSON.parse(response.result); } else { throw new Error(获取数据失败: ${response.responseCode}); } } catch (error) { console.error(获取数据异常:, error); throw error; } } async getPostDetail(id: number): Promiseany { try { const response await this.httpRequest.request( https://jsonplaceholder.typicode.com/posts/${id}, { method: http.RequestMethod.GET, header: { Content-Type: application/json } } ); if (response.responseCode 200) { return JSON.parse(response.result); } else { throw new Error(获取详情失败: ${response.responseCode}); } } catch (error) { console.error(获取详情异常:, error); throw error; } } }场景3带认证的请求import http from ohos.net.http; import preferences from ohos.data.preferences; class SecureApiService { private httpRequest: http.HttpRequest; private preferences: preferences.Preferences; constructor(context: common.UIAbilityContext) { this.httpRequest http.createHttp(); this.preferences preferences.getPreferencesSync(context, authData); } private async getAuthHeader(): Promiseany { const token await this.preferences.get(token, ); return { Content-Type: application/json, Authorization: Bearer ${token} }; } async getUserProfile(): Promiseany { try { const headers await this.getAuthHeader(); const response await this.httpRequest.request( https://api.example.com/user/profile, { method: http.RequestMethod.GET, header: headers } ); if (response.responseCode 200) { return JSON.parse(response.result); } else if (response.responseCode 401) { // token过期需要重新登录 throw new Error(认证失败请重新登录); } else { throw new Error(获取用户信息失败: ${response.responseCode}); } } catch (error) { console.error(获取用户信息异常:, error); throw error; } } async updateUserProfile(data: any): Promiseany { try { const headers await this.getAuthHeader(); const response await this.httpRequest.request( https://api.example.com/user/profile, { method: http.RequestMethod.PUT, header: headers, extraData: JSON.stringify(data) } ); if (response.responseCode 200) { return JSON.parse(response.result); } else if (response.responseCode 401) { throw new Error(认证失败请重新登录); } else { throw new Error(更新用户信息失败: ${response.responseCode}); } } catch (error) { console.error(更新用户信息异常:, error); throw error; } } }10. 错误处理与重试机制错误处理示例import http from ohos.net.http; class ApiClient { private httpRequest: http.HttpRequest; constructor() { this.httpRequest http.createHttp(); } async requestWithRetry( url: string, options: http.HttpRequestOptions, maxRetries: number 3 ): Promisehttp.HttpResponse { let lastError: Error; for (let attempt 1; attempt maxRetries; attempt) { try { const response await this.httpRequest.request(url, options); if (response.responseCode 200 response.responseCode 300) { return response; } // 如果是服务器错误重试 if (response.responseCode 500) { console.warn(服务器错误第${attempt}次重试: ${response.responseCode}); await this.delay(1000 * attempt); // 指数退避 continue; } // 客户端错误不重试 throw new Error(请求失败: ${response.responseCode}); } catch (error) { lastError error; console.warn(网络异常第${attempt}次重试:, error.message); if (attempt maxRetries) { await this.delay(1000 * attempt); } } } throw lastError || new Error(请求失败); } private delay(ms: number): Promisevoid { return new Promise(resolve setTimeout(resolve, ms)); } }11. 性能优化与最佳实践1. 请求复用import http from ohos.net.http; // 单例模式管理HTTP请求 class HttpManager { private static instance: HttpManager; private httpRequest: http.HttpRequest; private constructor() { this.httpRequest http.createHttp(); this.httpRequest.setTimeout(10000); } static getInstance(): HttpManager { if (!HttpManager.instance) { HttpManager.instance new HttpManager(); } return HttpManager.instance; } async request(url: string, options: http.HttpRequestOptions): Promisehttp.HttpResponse { return await this.httpRequest.request(url, options); } }2. 请求取消import http from ohos.net.http; class CancelableRequest { private httpRequest: http.HttpRequest; private isCanceled: boolean false; constructor() { this.httpRequest http.createHttp(); } async request(url: string, options: http.HttpRequestOptions): Promisehttp.HttpResponse { if (this.isCanceled) { throw new Error(请求已取消); } try { const response await this.httpRequest.request(url, options); if (this.isCanceled) { throw new Error(请求已取消); } return response; } catch (error) { if (this.isCanceled) { throw new Error(请求已取消); } throw error; } } cancel() { this.isCanceled true; // 注意目前HTTP模块不支持直接取消请求需要手动标记 } }3. 请求拦截器import http from ohos.net.http; import preferences from ohos.data.preferences; class InterceptorService { private httpRequest: http.HttpRequest; private preferences: preferences.Preferences; constructor(context: common.UIAbilityContext) { this.httpRequest http.createHttp(); this.preferences preferences.getPreferencesSync(context, authData); } // 请求拦截器 private async requestInterceptor(options: http.HttpRequestOptions): Promisehttp.HttpRequestOptions { // 添加认证token const token await this.preferences.get(token, ); if (token) { options.header options.header || {}; options.header[Authorization] Bearer ${token}; } // 添加公共请求头 options.header { Content-Type: application/json, User-Agent: MyApp/1.0, ...options.header }; return options; } // 响应拦截器 private responseInterceptor(response: http.HttpResponse): http.HttpResponse { if (response.responseCode 401) { // token过期处理 this.handleTokenExpired(); throw new Error(认证过期请重新登录); } return response; } private handleTokenExpired() { // 清除token跳转到登录页 this.preferences.delete(token); // router.replaceUrl({ url: pages/LoginPage }); } async request(url: string, options: http.HttpRequestOptions): Promisehttp.HttpResponse { const processedOptions await this.requestInterceptor(options); const response await this.httpRequest.request(url, processedOptions); return this.responseInterceptor(response); } }三、总结网络请求的核心要点✅ 核心知识点回顾HTTP模块基础掌握http.createHttp()创建请求对象支持GET、POST、PUT、DELETE等方法请求配置设置请求头、请求体、超时时间等参数数据格式支持JSON、FormData等多种数据格式错误处理正确处理网络异常、服务器错误、认证失败等情况性能优化实现请求复用、请求取消、重试机制等优化策略⚠️ 常见问题与解决方案网络权限问题确保在config.json中声明ohos.permission.INTERNET权限跨域问题服务器需要配置CORS或者使用代理服务器HTTPS证书问题确保服务器使用有效的SSL证书请求超时合理设置超时时间实现重试机制内存泄漏及时释放HTTP请求对象避免内存泄漏 最佳实践建议封装请求服务将HTTP请求封装到独立的服务类中提高代码复用性错误统一处理实现统一的错误处理机制避免重复代码请求拦截器使用拦截器统一处理认证、日志、错误等公共逻辑性能监控监控网络请求性能优化慢请求安全考虑敏感数据使用HTTPS加密传输token安全存储