合肥商城网站建设多少钱/南京seo建站

合肥商城网站建设多少钱,南京seo建站,如何做家政网站,北京故宫网站建设分析相关资源: 图片素材📎图片素材.zip 接口文档 1. HTTP 数据请求 什么是HTTP数据请求: (鸿蒙)应用软件可以通过(鸿蒙)系统内置的 http 模块 和 Axios,通过 HTTP 协议和服务器进行通讯 学习核心Http请求技术: Http模块 - 属于鸿…

相关资源:

  1. 图片素材📎图片素材.zip

接口文档

1. HTTP 数据请求

什么是HTTP数据请求:

(鸿蒙)应用软件可以通过(鸿蒙)系统内置的 http 模块 和 Axios,通过 HTTP 协议服务器进行通讯

学习核心Http请求技术:

  1. Http模块 - 属于鸿蒙内置模块,安全性较高,如果是银行项目都是Http模块
  2. Axios模块(第三方) - C端(B端)项目可以用开源的axios模块
  3. 鸿蒙、android,iOS 的原生App开发无需考虑跨域问题

2. http模块基本用法

咱们来看看 http 模块如何使用

传送门

// 1. 导入模块
import { http } from '@kit.NetworkKit'// 2. 创建请求对象
const request = http.createHttp();// 3. 调用request方法进行服务器请求
request.request('Url地址?key1=value1&key2=value2',{//GET(默认请求方式)、POST、PUT、DELETE,method:http.RequestMethod.GET,  // 如果是Get之外的请求->必填//OBJECT:服务器返回数据类型自动转换成对象(方便调用)// STRING:服务器返回的数据是一个字符串expectDataType:http.HttpDataType.OBJECT, // 必填// 设置请求头为json格式header:{  // 选填:Get请求有参数时+POST+PUT请求必填,其他选填'Content-Type':'application/json'},// 用来给Get,POST,PUT携带参数用// Get请求:  url?key=value// POST,PUT请求:在请求体中携带// 选填:Get请求有参数时+POST+PUT请求必填,其他选填extraData:{// 'key':'value'  //具体值来自接口文档pname:'湖南省'}
}).then((res:http.HttpResponse)=>{// 成功响应console.log(JSON.stringify(res.result))}).catch((err:Error)=>{// 失败处理console.log(JSON.stringify(err))})

注意:

  1. 预览器 和 模拟器 以及真机都可以发送请求
    1. 预览器无需配置网络权限即可成功发送请求
    2. 【模拟器】和【真机】需要配置网络权限才能成功发送请求

  1. 配置权限 -> 详细权限设置,可以参考 声明权限 权限列表
    1. 需要在项目的src/main/module.json5(模块配置)下添加如下代码
{"module": {"name": "entry","type": "entry","description": "$string:module_desc","mainElement": "EntryAbility","deviceTypes": ["phone","tablet","2in1"],"deliveryWithInstall": true,"installationFree": false,"pages": "$profile:main_pages","requestPermissions": [{"name": "ohos.permission.INTERNET"}],"abilities": [{"name": "EntryAbility","srcEntry": "./ets/entryability/EntryAbility.ets","description": "$string:EntryAbility_desc","icon": "$media:layered_image","label": "$string:EntryAbility_label","startWindowIcon": "$media:startIcon","startWindowBackground": "$color:start_window_background","exported": true,"skills": [{"entities": ["entity.system.home"],"actions": ["action.system.home"]}]}]}
}

2.1. Get请求演示

获取一条随机笑话:https://api-vue-base.itheima.net/api/joke

import { http } from '@kit.NetworkKit'@Entry
@Component
struct Notebook_use {@State message: string = 'Hello World';build() {Row() {Column() {Text(this.message).fontSize(20)Button('看笑话').onClick(() => {const req = http.createHttp()req.request('https://api-vue-base.itheima.net/api/joke',{method: http.RequestMethod.GET,expectDataType:http.HttpDataType.STRING}).then((res: http.HttpResponse) => {// AlertDialog.show({ message: JSON.stringify(res,null,2) })this.message = res.result.toString()})})}.width('100%')}.height('100%')}
}

获取新闻列表数据:https://hmajax.itheima.net/api/news

import { http } from '@kit.NetworkKit'interface NewsResponse {message: stringdata: News[]
}interface News {id: numbertitle: stringsource: stringcmtcount: numberimg: stringtime: string
}@Entry
@Component
struct Day01_02_URL {@State data: NewsResponse | null = nullbuild() {Column() {Button('获取新闻列表数据').onClick(() => {//   1. 创建请求对象const req = http.createHttp()//   2. 发送请求获取服务器数据//   http://hmajax.itheima.net/api/newsreq.request('http://hmajax.itheima.net/api/news', {expectDataType: http.HttpDataType.OBJECT}).then(res => {console.log(JSON.stringify(res.result))this.data = res.result as NewsResponse})})// Text(JSON.stringify(this.data,null,2))}.height('100%').width('100%')}
}

地址:http://hmajax.itheima.net/api/city

说明获取某个省所有的城市查询

参数名:pname

说明: 传递省份或直辖市名,比如 北京、广东省…

import { http } from '@kit.NetworkKit'@Entry
@Component
struct Index {build() {Column() {Button('获取城市信息').onClick(() => {const req = http.createHttp()req.request('http://hmajax.itheima.net/api/city', {expectDataType:http.HttpDataType.OBJECT,extraData:{pname:'广东省'}}).then(res=>{console.log(JSON.stringify(res.result))}).catch((err:Error)=>{console.log(JSON.stringify(err,null,2))})})}.height('100%').width('100%')}
}

2.2. POST请求演示

注册用户:接口文档


@Entry
@Component
struct Day01_05_SubmitData {@State username: string = ''@State password: string = ''build() {Column({ space: 15 }) {Text('请求方法和数据提交').fontSize(30).fontWeight(FontWeight.Bold)// $$this.username 双向数据绑定TextInput({ text: $$this.username, placeholder: '用户名' })TextInput({ text: $$this.password, placeholder: '密码' }).type(InputType.Password)Button('注册').width('100%').onClick(() => {Button('登录').width('100%').onClick(() => {})}.width('100%').height('100%').padding(20)}
}
import http from '@ohos.net.http'const req = http.createHttp()@Entry
@Component
struct Day01_05_SubmitData {@State username: string = 'itheima522'@State password: string = '123456'build() {Column({ space: 15 }) {Text('请求方法和数据提交').fontSize(30).fontWeight(FontWeight.Bold)TextInput({ text: $$this.username, placeholder: '用户名' })TextInput({ text: $$this.password, placeholder: '密码' }).type(InputType.Password)Button('注册').width('100%').onClick(() => {req.request('http://hmajax.itheima.net/api/register', {method: http.RequestMethod.POST,expectDataType:http.HttpDataType.OBJECT,header: {contentType: 'application/json'},extraData: {username: this.username,password: this.password}}).then(res => {AlertDialog.show({ message:JSON.stringify(res.result,null,2) })})})     }.width('100%').height('100%').padding(20)}
}

2.3. 模拟器和真机网络权限配置

预览器的网络请求无需配置网络请求权限

模拟器和真机必须要配置网络权限才能进行网络请求

如果没有配置网络请求权限,则在请求后会出现如下错误:

如何配置网络权限?

在项目中找到entry/src/main/module.json5 文件,在里面配置网络请求

权限列表

{"module": {"name": "entry","type": "entry","description": "$string:module_desc","mainElement": "EntryAbility","deviceTypes": ["phone","tablet","2in1"],"deliveryWithInstall": true,"installationFree": false,"pages": "$profile:main_pages","requestPermissions": [{"name": "ohos.permission.INTERNET"}],"abilities": [{"name": "EntryAbility","srcEntry": "./ets/entryability/EntryAbility.ets","description": "$string:EntryAbility_desc","icon": "$media:layered_image","label": "$string:EntryAbility_label","startWindowIcon": "$media:startIcon","startWindowBackground": "$color:start_window_background","exported": true,"skills": [{"entities": ["entity.system.home"],"actions": ["action.system.home"]}]}],"extensionAbilities": [{"name": "EntryBackupAbility","srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets","type": "backup","exported": false,"metadata": [{"name": "ohos.extension.backup","resource": "$profile:backup_config"}]}]}
}

3. 案例-开心一笑

接下来完成一个案例,需求:

  1. 默认获取若干条笑话,并渲染到页面上
  2. 下拉刷新
  3. 触底加载更多
  4. 点击返回顶部

3.1. 前置知识

3.1.1. Refresh下拉刷新容器组件

作用:可以实现下拉刷新功能

@Entry
@Component
struct Index {// 1. 控制Refresh组件的下拉动画效果的,true:打开下拉刷新效果 false:关闭下拉刷新效果@State isrefreshing: boolean = falsebuild() {Column() {Refresh({ refreshing: $$this.isrefreshing }) {List({ space: 5 }) {ForEach([1, 2, 3, 4, 5, 6, 7, 8], () => {ListItem() {Row() {}.height(100).width('100%').backgroundColor(Color.Pink)}})}}// 只要一下拉就会触发这个事件.onRefreshing(() => {// AlertDialog.show({ message: 'ok' })setTimeout(() => {this.isrefreshing = false // 关闭刷新}, 3000)})}.height('100%').width('100%')}
}

3.1.2. LoadingProgress正在加载中的动画图标

    LoadingProgress().height(50).color(Color.Red)

3.1.3. List的触底事件 .onReachEnd()

作用:可以实现List列表数据触底时加载

@Entry
@Component
struct Index {@State isLoding: boolean = falsebuild() {Column() {List({ space: 5 }) {ForEach([1, 2, 3, 4, 5, 6, 7, 8], () => {ListItem() {Row() {}.height(100).width('100%').backgroundColor(Color.Pink)}})// 加一个正在加载中的动画ListItem() {LoadingProgress().height(50)}.width('100%')}// onReachEnd当List的滚动条滚动到底部的时候会触发// ✨✨问题:鼠标一抖动触发了/* 解决方案:设置一个状态变量初始值为false,在onReachEnd中加一个if判断 -> 方法体里面将这个变量的值设置为true,直到服务器返回了数据后,重置这个变量的值为false✨✨onReachEnd特点:页面加载的时候从服务器获取到数据之后会自动触发*/.onReachEnd(() => {// 我们可以发请求拿新数据if (this.isLoding == false) {this.isLoding = truesetTimeout(() => {AlertDialog.show({ message: '触底加载' })this.isLoding = false}, 3000)}})}.height('100%').width('100%')}
}

3.2. 基本结构

/*** 1. 默认加载* 2. 下拉刷新* 3. 触底加载更多* 4. 点击返回顶部* */
@Entry
@Component
struct Day01_07_Jokes {@State jokes: string [] = ['笑话 1']build() {Column() {// 顶部this.HeaderBuilder()// 笑话列表List({ space: 10 }) {ForEach(this.jokes, (joke: string) => {ListItem() {Column({ space: 10 }) {Text('笑话标题').fontSize(20).fontWeight(600)Row({ space: 15 }) {titleIcon({ icon: $r('app.media.ic_public_time'), info: '2024-1-1' })titleIcon({ icon: $r('app.media.ic_public_read'), info: '阅读(6666)' })titleIcon({ icon: $r('app.media.ic_public_comments'), info: '评论(123)' })}Text(joke).fontSize(15).fontColor(Color.Gray)}.width('100%').alignItems(HorizontalAlign.Start).padding(20)}.borderRadius(10).backgroundColor(Color.White).shadow({ radius: 2, color: Color.Gray })})}.padding(10).layoutWeight(1)}.width('100%').height('100%').backgroundColor('#f6f6f6')}@BuilderHeaderBuilder() {Row() {Image($r('app.media.ic_public_drawer_filled')).width(25);Image($r('app.media.ic_public_joke_logo')).width(30)Image($r('app.media.ic_public_search')).width(30);}.width('100%').justifyContent(FlexAlign.SpaceBetween).height(60).padding(10).border({ width: { bottom: 2 }, color: '#f0f0f0' }).backgroundColor(Color.White)}
}@Component
struct titleIcon {icon: ResourceStr = ''info: string = ''build() {Row() {Image(this.icon).width(15).fillColor(Color.Gray)Text(this.info).fontSize(14).fontColor(Color.Gray)}}
}

3.3. 默认获取若干条笑话

核心步骤:

  1. 生命周期函数中获取数据
    1. aboutToAppear
    2. http 模块获取笑话,若干条

请求地址:https://api-vue-base.itheima.net/api/joke/list

参数:num

完整url:https://api-vue-base.itheima.net/api/joke/list?num=获取条数

  1. 将获取到的数据转换格式并渲染
    1. as 类型

import { http } from '@kit.NetworkKit'export interface iItem {code: number;data: string[];msg: string;
}/*** 1. 默认加载 -> 加载五条数据 -> aboutToAppear() -> getList()* 2. 下拉刷新* 3. 触底加载更多* 4. 点击返回顶部* */
@Entry
@Component
struct Day01_07_Jokes {@State jokes: string [] = ['笑话 1']aboutToAppear(): void {this.getList()}// 请求笑话数据async getList() {const req = http.createHttp()try {const res = await req.request('https://api-vue-base.itheima.net/api/joke/list', {expectDataType: http.HttpDataType.OBJECT,extraData: {num: '5'}})// 将res.reslut这个Object对象as成真正的接口类型,才能使用里面的属性const obj = res.result as iItemthis.jokes = obj.data// AlertDialog.show({ message: JSON.stringify(obj.data, null, 2) })} catch (err) {AlertDialog.show({ message: '网络错误' })}}build() {Column() {// 顶部this.HeaderBuilder()// 笑话列表List({ space: 10 }) {ForEach(this.jokes, (joke: string) => {ListItem() {Column({ space: 10 }) {Text('笑话标题').fontSize(20).fontWeight(600)Row({ space: 15 }) {titleIcon({ icon: $r('app.media.ic_public_time'), info: '2024-1-1' })titleIcon({ icon: $r('app.media.ic_public_read'), info: '阅读(6666)' })titleIcon({ icon: $r('app.media.ic_public_comments'), info: '评论(123)' })}Text(joke).fontSize(15).fontColor(Color.Gray)}.width('100%').alignItems(HorizontalAlign.Start).padding(20)}.borderRadius(10).backgroundColor(Color.White).shadow({ radius: 2, color: Color.Gray })})}.padding(10).layoutWeight(1)}.width('100%').height('100%').backgroundColor('#f6f6f6')}@BuilderHeaderBuilder() {Row() {Image($r('app.media.ic_public_drawer_filled')).width(25);Image($r('app.media.ic_public_joke_logo')).width(30)Image($r('app.media.ic_public_search')).width(30);}.width('100%').justifyContent(FlexAlign.SpaceBetween).height(60).padding(10).border({ width: { bottom: 2 }, color: '#f0f0f0' }).backgroundColor(Color.White)}
}@Component
struct titleIcon {icon: ResourceStr = ''info: string = ''build() {Row() {Image(this.icon).width(15).fillColor(Color.Gray)Text(this.info).fontSize(14).fontColor(Color.Gray)}}
}

3.4. 下拉刷新

核心步骤:

  1. 通过 Refresh组件实现下拉效果
  2. 在 onRefreshing 中重新获取数据替换默认值即可
  3. 抽取获取笑话的方法,在 2 个地方调用即可
    1. aboutToAppear
    2. onRefreshing
      1. 延迟关闭下拉刷新的效果

/*** 1. 默认加载* 2. 下拉刷新* 3. 触底加载更多* 4. 点击返回顶部* */
import { http } from '@kit.NetworkKit'interface iData {code: numbermsg: stringdata: string[]
}@Entry
@Component
struct Day01_07_Jokes {@State jokes: string [] = ['笑话 1']@State isrefreshing:boolean = false// 1. 页面渲染完成后调用声明周期方法aboutToAppear(): void {this.getList().then(res => {let objData: iData = JSON.parse(res.result.toString())this.jokes = objData.data})}// 获取笑话数据getList() {//  请求服务器数据const req = http.createHttp()// 返回对象return req.request('https://api-vue-base.itheima.net/api/joke/list?num=5')}build() {Column() {// 顶部this.HeaderBuilder()// 笑话列表Refresh({refreshing:$$this.isrefreshing}) {List({ space: 10 }) {ForEach(this.jokes, (joke: string) => {ListItem() {Column({ space: 10 }) {Text(joke.slice(0, 10))// 从字符串中截取前若干个文字.fontSize(20).fontWeight(600)Row({ space: 15 }) {titleIcon({ icon: $r('app.media.ic_public_time'), info: '2024-1-1' })titleIcon({ icon: $r('app.media.ic_public_read'), info: '阅读(6666)' })titleIcon({ icon: $r('app.media.ic_public_comments'), info: '评论(123)' })}Text(joke).fontSize(15).fontColor(Color.Gray)}.width('100%').alignItems(HorizontalAlign.Start).padding(20)}.borderRadius(10).backgroundColor(Color.White).shadow({ radius: 2, color: Color.Gray })})}.padding(10).layoutWeight(1)}.onRefreshing(()=>{// 重新请求服务器获取新数据this.getList().then(res=>{// 刷新列表let objData: iData = JSON.parse(res.result.toString())this.jokes = objData.data//服务器返回数据后,关闭下拉加载功能this.isrefreshing = false })})}.width('100%').height('100%').backgroundColor('#f6f6f6')}@BuilderHeaderBuilder() {Row() {Image($r('app.media.ic_public_drawer_filled')).width(25);Image($r('app.media.ic_public_joke_logo')).width(30)Image($r('app.media.ic_public_search')).width(30);}.width('100%').justifyContent(FlexAlign.SpaceBetween).height(60).padding(10).border({ width: { bottom: 2 }, color: '#f0f0f0' }).backgroundColor(Color.White)}
}@Component
struct titleIcon {icon: ResourceStr = ''info: string = ''build() {Row() {Image(this.icon).width(15).fillColor(Color.Gray)Text(this.info).fontSize(14).fontColor(Color.Gray)}}
}

3.5. 触底加载更多

核心步骤:

  1. 在 onReachEnd 事件中加载更多数据,list 组件
    1. 重新获取数据
    2. 和本地的合并到一起
    3. this.jokes.push(...['笑话 1',’笑话 2‘])
  1. 获取到的数据和本地数据合并
/*** 1. 默认加载* 2. 下拉刷新* 3. 触底加载更多* 4. 点击返回顶部* */
import { http } from '@kit.NetworkKit'interface iData {code: numbermsg: stringdata: string[]
}@Entry
@Component
struct Day01_07_Jokes {@State jokes: string [] = []@State isrefreshing: boolean = false@State isLoadMore: boolean = false //控制触底加载// 1. 页面渲染完成后调用声明周期方法aboutToAppear(): void {// this.getList()//   .then(res => {//     let objData: iData = JSON.parse(res.result.toString())//     this.jokes = objData.data//   })}// 获取笑话数据getList() {//  请求服务器数据const req = http.createHttp()// 返回对象return req.request('https://api-vue-base.itheima.net/api/joke/list?num=5')}build() {Column() {// 顶部this.HeaderBuilder()// 笑话列表Refresh({ refreshing: $$this.isrefreshing }) {List({ space: 10 }) {ForEach(this.jokes, (joke: string) => {ListItem() {Column({ space: 10 }) {Text(joke.slice(0, 10))// 从字符串中截取前若干个文字.fontSize(20).fontWeight(600)Row({ space: 15 }) {titleIcon({ icon: $r('app.media.ic_public_time'), info: '2024-1-1' })titleIcon({ icon: $r('app.media.ic_public_read'), info: '阅读(6666)' })titleIcon({ icon: $r('app.media.ic_public_comments'), info: '评论(123)' })}Text(joke).fontSize(15).fontColor(Color.Gray)}.width('100%').alignItems(HorizontalAlign.Start).padding(20)}.borderRadius(10).backgroundColor(Color.White).shadow({ radius: 2, color: Color.Gray })})// TODO:触底加载更多的动画提示ListItem() {LoadingProgress().height(50)}.width('100%')}.onReachEnd(() => {if (this.isLoadMore == false) {this.isLoadMore = true//  发送新的请求获取新数据新数据应该是追加到this.jokes的后面-> pushthis.getList().then(res => {let objData: iData = JSON.parse(res.result.toString())// 将服务器新返回的数据展开之后追加原数组的后边this.jokes.push(...objData.data)this.isLoadMore = false})}}).padding(10).layoutWeight(1)}.onRefreshing(() => {// 请求服务器获取新数据this.getList().then(res => {let objData: iData = JSON.parse(res.result.toString())this.jokes = objData.data//等服务器返回数据后关闭下拉加载功能this.isrefreshing = false})})}.width('100%').height('100%').backgroundColor('#f6f6f6')}@BuilderHeaderBuilder() {Row() {Image($r('app.media.ic_public_drawer_filled')).width(25);Image($r('app.media.ic_public_joke_logo')).width(30)Image($r('app.media.ic_public_search')).width(30);}.width('100%').justifyContent(FlexAlign.SpaceBetween).height(60).padding(10).border({ width: { bottom: 2 }, color: '#f0f0f0' }).backgroundColor(Color.White)}
}@Component
struct titleIcon {icon: ResourceStr = ''info: string = ''build() {Row() {Image(this.icon).width(15).fillColor(Color.Gray)Text(this.info).fontSize(14).fontColor(Color.Gray)}}
}

3.6. 点击【顶部栏】返回顶部

核心步骤:

  1. 【顶部栏】点击事件中通过 Scroller控制器 scrollEdge 方法滚到顶部
    1. 通过控制器的方法,滚到顶部即可
/*** 1. 默认加载* 2. 下拉刷新* 3. 触底加载更多* 4. 点击返回顶部* */
import { http } from '@kit.NetworkKit'interface iData {code: numbermsg: stringdata: string[]
}@Entry
@Component
struct Day01_07_Jokes {@State jokes: string [] = []@State isrefreshing: boolean = false@State isLoadMore: boolean = false //控制触底加载listScroller = new ListScroller()// 1. 页面渲染完成后调用声明周期方法aboutToAppear(): void {// this.getList()//   .then(res => {//     let objData: iData = JSON.parse(res.result.toString())//     this.jokes = objData.data//   })}// 获取笑话数据getList() {//  请求服务器数据const req = http.createHttp()// 返回对象return req.request('https://api-vue-base.itheima.net/api/joke/list?num=5')}build() {Column() {// 顶部this.HeaderBuilder()// 笑话列表Refresh({ refreshing: $$this.isrefreshing }) {List({ space: 10, scroller: this.listScroller }) {ForEach(this.jokes, (joke: string) => {ListItem() {Column({ space: 10 }) {Text(joke.slice(0, 10))// 从字符串中截取前若干个文字.fontSize(20).fontWeight(600)Row({ space: 15 }) {titleIcon({ icon: $r('app.media.ic_public_time'), info: '2024-1-1' })titleIcon({ icon: $r('app.media.ic_public_read'), info: '阅读(6666)' })titleIcon({ icon: $r('app.media.ic_public_comments'), info: '评论(123)' })}Text(joke).fontSize(15).fontColor(Color.Gray)}.width('100%').alignItems(HorizontalAlign.Start).padding(20)}.borderRadius(10).backgroundColor(Color.White).shadow({ radius: 2, color: Color.Gray })})// TODO:触底加载更多的动画提示ListItem() {LoadingProgress().height(50)}.width('100%')}.onReachEnd(() => {if (this.isLoadMore == false) {this.isLoadMore = true//  发送新的请求获取新数据新数据应该是追加到this.jokes的后面-> pushthis.getList().then(res => {let objData: iData = JSON.parse(res.result.toString())// 将服务器新返回的数据展开之后追加原数组的后边this.jokes.push(...objData.data)this.isLoadMore = false})}}).padding(10).layoutWeight(1)}.onRefreshing(() => {// 请求服务器获取新数据this.getList().then(res => {let objData: iData = JSON.parse(res.result.toString())this.jokes = objData.data//等服务器返回数据后关闭下拉加载功能this.isrefreshing = false})})}.width('100%').height('100%').backgroundColor('#f6f6f6')}@BuilderHeaderBuilder() {Row() {Image($r('app.media.ic_public_drawer_filled')).width(25);Image($r('app.media.ic_public_joke_logo')).width(30)Image($r('app.media.ic_public_search')).width(30);}.onClick(() => {//   点击滚动到顶部this.listScroller.scrollEdge(Edge.Top)}).width('100%').justifyContent(FlexAlign.SpaceBetween).height(60).padding(10).border({ width: { bottom: 2 }, color: '#f0f0f0' }).backgroundColor(Color.White)}
}@Component
struct titleIcon {icon: ResourceStr = ''info: string = ''build() {Row() {Image(this.icon).width(15).fillColor(Color.Gray)Text(this.info).fontSize(14).fontColor(Color.Gray)}}
}

4. 请求库-axios

除了原生的请求库http以外,还可以使用 第三方请求库axios来进行网络请求,为我们提供第二种http请求方式

axios文档传送门

4.1. 基本用法

4.1.1. 下载axios

作为一个第三方库,使用的时候需要先完成下包的操作

打开终端执行命令

# 安装
ohpm i @ohos/axios# 卸载
ohpm uninstall @ohos/axios

ohpm 是一个包管理工具,用来管理鸿蒙提供的第三方模块

如果无法执行命令,或执行失败,可以使用如下方式来完成安装:

4.1.2. axios完成POST请求

基本语法格式:

// 1. 导入axios
// AxiosError:异常时的数据类型
// 正常时的数据类型AxiosResponse 是一个泛型类型
import axios, { AxiosError, AxiosResponse } from '@ohos/axios'// 2. 创建axios的对象实例
const req = axios.create()// 3. 发送POST请求,并提交数据给服务器
const res:AxiosResponse<响应数据类型> = await req<响应数据类型(可以写null), AxiosResponse<响应数据类型>, 请求体数据类型>({method: 'POST',  // 请求方法url: 'https://hmajax.itheima.net/api/login',  //服务器url地址data: { // 请求体数据username: '黑马no1hello',password: '123456'}})

登录接口传送门

import axios, { AxiosError, AxiosResponse } from '@ohos/axios'// 1. 利用axios.create创建请求对象
const reqeust = axios.create({baseURL: 'https://hmajax.itheima.net/'
})export interface iRes {/*** 业务状态码, 10000成功, 10004-账号/密码未携带*/code: number;/*** 响应数据*/data: object;/*** 响应消息*/message: string;
}export interface iBody {/*** 密码, 最少6位*/password: string;/*** 用户名, 最少8位,中英文和数字组成,*/username: string;
}@Entry
@Component
struct Index {build() {Column() {Button('post请求测试').onClick(async () => {//   2. 发起请求try {const res: AxiosResponse<iRes> = await reqeust<null, AxiosResponse<iRes>, iBody>({method: 'POST',url: 'api/login',data: {username: '黑马no1hello',password: '123456'}})AlertDialog.show({ message: JSON.stringify(res.data, null, 2) })} catch (err) {// 将err异常对象强制转换成 AxiosError// response就是异常的响应对象const error: AxiosError = err as AxiosErrorAlertDialog.show({ message: JSON.stringify(error.response, null, 2) })}})}.height('100%').width('100%').backgroundColor(Color.Pink)}
}
  1. 请求体有数据提交时,泛型参数 3,需要设置为【请求体】的格式,可以从 apifox 直接c+v

4.1.3. axios完成GET请求

一级商品(无参数) : 接口文档传送门

import axios, { AxiosError, AxiosResponse } from '@ohos/axios'export interface ApifoxModel {/*** 响应数据*/data: Datum[];/*** 响应消息*/message: string;
}export interface Datum {/*** 顶级分类id*/id: string;/*** 顶级分类名字*/name: string;/*** 顶级分类图片*/picture: string;
}@Entry
@Component
struct Index {build() {Column() {Button('axios.get').onClick(async () => {// 1. 创建请求实例const req = axios.create()// 2. async 和 await方式发送get请求(不带参数)try{let res: AxiosResponse<ApifoxModel> = await req({method: 'get',url: 'https://hmajax.itheima.net/api/category/top'})AlertDialog.show({ message: JSON.stringify(res.data, null, 2) })} catch (err) {let errObj: AxiosError = errAlertDialog.show({ message: '出错了:' + JSON.stringify(errObj.message, null, 2) })}// 3. .then().catch()方式发送请求(不带参数)// req.request({//   method: 'get',//   url: 'https://hmajax.itheima.net/api/category/top1'// })//   .then((res: AxiosResponse<ApifoxModel>) => {//     AlertDialog.show({ message: JSON.stringify(res.data, null, 2) })//   })//   .catch((err: AxiosError) => {//     AlertDialog.show({ message: '出错了:' + JSON.stringify(err, null, 2) })//   })})}.height('100%').width('100%')}
}

get 请求传递的查询参数

import axios, { AxiosError, AxiosResponse } from '@ohos/axios'export interface ApifoxModel {/*** 响应数据*/data: Data;/*** 响应消息*/message: string;
}/*** 响应数据*/
export interface Data {/*** 顶级分类下属二级分类数组*/children: Child[];/*** 顶级分类id*/id: string;/*** 顶级分类名字*/name: string;/*** 顶级分类图片*/picture: string;
}export interface Child {/*** 二级分类id*/id: string;/*** 二级分类名字*/name: string;/*** 二级分类图片*/picture: string;
}@Entry
@Component
struct Index {build() {Column() {Button('axios.get').onClick(async () => {// 1. 创建请求实例const req = axios.create()// 2. async 和 await方式发送get请求(带参数)try{let res: AxiosResponse<ApifoxModel> = await req({method: 'get',url: 'https://hmajax.itheima.net/api/category/sub',params:{id:'1005000'}})// 写法2:let res: AxiosResponse<ApifoxModel> = await req.get('https://hmajax.itheima.net/api/category/sub', {params: {id: '1005000'}})AlertDialog.show({ message: JSON.stringify(res.data, null, 2) })} catch (err) {let errObj: AxiosError = errAlertDialog.show({ message: '出错了:' + JSON.stringify(errObj.message, null, 2) })}// 3. .then().catch()方式发送请求(带参数)// req.request({// method: 'get',// url: 'https://hmajax.itheima.net/api/category/sub',// params:{//   id:'1005000'// }// })//   .then((res: AxiosResponse<ApifoxModel>) => {//     AlertDialog.show({ message: JSON.stringify(res.data, null, 2) })//   })//   .catch((err: AxiosError) => {//     AlertDialog.show({ message: '出错了:' + JSON.stringify(err, null, 2) })//   })})}.height('100%').width('100%')}
}

4.2. axios基地址配置

我们可以使用自定义配置新建一个实例

// 基于配置,返回一个 axios 的实例
const req =  axios.create({// 基地址,后续请求的时候这部分可以省略baseURL:'https://hmajax.itheima.net'
})
// get 请求 直接写 url 即可let res: AxiosResponse<ApifoxModel> = await req({method: 'get',url: '/api/category/top'
})
AlertDialog.show({ message: JSON.stringify(res) })

import axios, { AxiosResponse } from '@ohos/axios'
const req = axios.create({// ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨// 设置请求url的基地址,它的值一般填写后台数据接口服务器的域名// 注意点,最后要不要带 / 要看下边req.request()中的url中首字符是否有/// 如果有,不带,否则带//✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨baseURL:'https://hmajax.itheima.net'
})export interface iRes {/*** 响应数据*/data: Datum[];/*** 响应消息*/message: string;
}export interface Datum {/*** 顶级分类id*/id: string;/*** 顶级分类名字*/name: string;/*** 顶级分类图片*/picture: string;
}@Entry
@Component
struct Index {build() {Column({ space: 100 }) {Button('axios发送不带参数的请求').onClick(async () => {// const req = axios.create()try {// 此处编写代码let res: AxiosResponse<iRes> = await req({url: '/api/category/top',  //由于设置了基地址,所以此处只需要配置请求路径即可method: 'get', //默认值,可以省略})AlertDialog.show({ message: JSON.stringify(res.data, null, 2) })} catch (err) {AlertDialog.show({ message: JSON.stringify(err, null, 2) })}})Button('axios发送带参数的请求').onClick(async () => {// const req = axios.create()try {// 此处编写代码let res: AxiosResponse<iRes> = await req({url: '/api/city',  //由于设置了基地址,所以此处只需要配置请求路径即可method: 'get', //默认值,可以省略// get请求的参数是通过固定的属性:params来进行携带// post请求的参数是固定通过:data来携带的params: {pname: '广东省'  // 使用axios中文参数值再内部回自动转成url编码,服务器能够正常响应数据}})AlertDialog.show({ message: JSON.stringify(res.data, null, 2) })} catch (err) {AlertDialog.show({ message: JSON.stringify(err, null, 2) })}})}.height('100%').width('100%')}
}

注意:axios和内置的 http 模块在异常的处理上略有不同:

  1. 内置的 http 模块,http 状态码为异常时,不会响应为错误
  2. axios对于 http 状态码的错误(2xx 以外),会作为异常处理

5. 综合案例-我的书架-axios

图片素材

我的书架.zip

接口文档

接下来咱们使用 axios 来完成书架案例

5.1. 获取图书列表

5.1.1. 静态结构

@Entry
@Component
struct Index {// 1. 我的书架@BuilderMyBook() {Row() {Image($r('app.media.ic_public_drawer_filled')).height(20)Text('我的书架').fontSize(20).fontWeight(800)Image($r('app.media.ic_public_add')).height(20)}.width('100%').justifyContent(FlexAlign.SpaceBetween).padding(10).border({ width: { bottom: 1 }, color: { bottom: 'rgba(0,0,0,0.2)' } })}// 2. 书籍列表@BuilderBookList() {List() {ListItem() {// 布局Row({ space: 10 }) {Image($r('app.media.ic_public_cover')).width(100)Column({ space: 25 }) {Column() {Text('书名:').width('100%').fontSize(20).fontWeight(800)Text('作者:').width('100%').fontSize(14).fontWeight(600).fontColor('rgba(0,0,0,0.4)').padding({ top: 5 })}Text('出版社:').width('100%').fontWeight(600).fontColor('rgba(0,0,0,0.4)')}.layoutWeight(1)}.padding(10)}.swipeAction({end: this.delBuilder()})}}// 3. 删除书籍的构建函数@BuilderdelBuilder() {Column(){Text('删除').backgroundColor(Color.Red).fontColor(Color.White).height('100%').width(60).textAlign(TextAlign.Center)}.padding(10)}build() {Column() {// 1. 我的书架this.MyBook()// 2. 书籍列表this.BookList()}.height('100%').width('100%')}
}

5.1.2. 准备类型模块并导出

由于图书的增,改,列表,详情接口返回的数据对象是一样的。所以我们可以在这些业务中可以共用同一个interface类型,因此,需要进行模块封装并导出

export interface iBookResponse {/*** 响应数组*/data: iBookInfo[];/*** 响应消息*/message: string;
}// 按需导出
export interface iBookInfo {/*** 图书作者*/author: string;/*** 图书名字*/bookname: string;/*** 图书id*/id: number;/*** 图书出版社*/publisher: string;
}

5.1.3. 获取图书数据并渲染

import axios, { AxiosResponse } from '@ohos/axios'
import { iBookInfo, iBookResponse } from './models'
import { router } from '@kit.ArkUI'const req = axios.create()@Entry
@Component
struct Index {@State bookList: iBookInfo[] = []aboutToAppear(): void {this.getBookList()}async getBookList() {try {let res: AxiosResponse<iBookResponse> =await req.request({url: 'https://hmajax.itheima.net/api/books',params:{creator:'ivan'}})this.bookList = res.data.data} catch (err) {AlertDialog.show({message:JSON.stringify(err,null,2)})}}build() {Column() {// 1. 我的书架this.MyBook()// 2. 书籍列表this.BookList()}.height('100%').width('100%')}// 1. 我的书架@BuilderMyBook() {Row() {Image($r('app.media.ic_public_drawer_filled')).height(20)Text('我的书架').fontSize(20).fontWeight(800)Image($r('app.media.ic_public_add')).height(20).onClick(()=>{router.pushUrl({url:'pages/axiosbooks/addBook'})})}.width('100%').justifyContent(FlexAlign.SpaceBetween).padding(10).border({ width: { bottom: 1 }, color: { bottom: 'rgba(0,0,0,0.2)' } })}// 2. 书籍列表@BuilderBookList() {List() {ForEach(this.bookList, (item: iBookInfo) => {ListItem() {// 布局Row({ space: 10 }) {Image($r('app.media.ic_public_cover')).width(100)Column({ space: 25 }) {Column() {Text('书名:'+item.bookname).width('100%').fontSize(20).fontWeight(800)Text('作者:'+item.author).width('100%').fontSize(14).fontWeight(600).fontColor('rgba(0,0,0,0.4)').padding({ top: 5 })}Text('出版社:').width('100%').fontWeight(600).fontColor('rgba(0,0,0,0.4)')}.layoutWeight(1)}.padding(10)}.swipeAction({end: this.delBuilder()})})}}// 3. 删除书籍的构建函数@BuilderdelBuilder() {Column() {Text('删除').backgroundColor(Color.Red).fontColor(Color.White).height('100%').width(60).textAlign(TextAlign.Center)}.padding(10)}
}

5.2. 新增图书

5.2.1. 静态结构

// 导入创建者
import { creator } from './models'@Entry
@Component
struct addPage {@State bookname: string = ''@State author: string = ''@State publisher: string = ''build() {Navigation() {Column({ space: 10 }) {Row() {Text('图书名称:')TextInput({ placeholder: '请输入图书名字', text: $$this.bookname })}Row() {Text('图书作者:')TextInput({ placeholder: '请输入作者名字', text: $$this.author })}Row() {Text('图书出版社:')TextInput({ placeholder: '请输入出版社名字', text: $$this.publisher })}Button({ type: ButtonType.Normal }) {Text('保存').fontColor(Color.White).fontWeight(800)}.width('100%').height(40).borderRadius(8)}.height('100%').width('100%').padding(10)}.title('新增图书').titleMode(NavigationTitleMode.Mini)}
}

5.2.2. 新增逻辑实现

// 导入创建者
import axios, { AxiosResponse } from '@ohos/axios'
import { creator, iBookInfoDetial } from './models'
import { promptAction, router } from '@kit.ArkUI';// POST请求体数据类型
export interface iReqeustBody {/*** 新增图书作者*/author: string;/*** 新增图书名字*/bookname: string;/*** 新增图书创建者,自己的外号,和获取图书时的外号相同*/creator: string;/*** 新增图书出版社*/publisher: string;
}@Entry
@Component
struct addPage {@State bookname: string = ''@State author: string = ''@State publisher: string = ''async addBook() {//  1. 非空验证 -> 轻提示用户if (this.bookname == '' || this.author == '' || this.publisher == '') {promptAction.showToast({ message: '图书名,作者,出版社均非空' })return //阻止下面代码继续执行}const req = axios.create()let res: AxiosResponse<iBookInfoDetial> = await req.request<null, AxiosResponse<iBookInfoDetial>, iReqeustBody>({method: 'POST',url: 'https://hmajax.itheima.net/api/books',data: {bookname: this.bookname,author: this.author,publisher: this.publisher,creator: creator}})promptAction.showToast({ message: res.data.message })router.back()}build() {Navigation() {Column({ space: 10 }) {Row() {Text('图书名称:')TextInput({ placeholder: '请输入图书名字', text: $$this.bookname })}Row() {Text('图书作者:')TextInput({ placeholder: '请输入作者名字', text: $$this.author })}Row() {Text('图书出版社:')TextInput({ placeholder: '请输入出版社名字', text: $$this.publisher })}Button({ type: ButtonType.Normal }) {Text('保存').fontColor(Color.White).fontWeight(800)}.width('100%').height(40).borderRadius(8).onClick(() => {this.addBook()})}.height('100%').width('100%').padding(10)}.title('新增图书').titleMode(NavigationTitleMode.Mini)}
}

5.3. 删除图书

import axios, { AxiosResponse } from '@ohos/axios'
import { iBookInfo, iBookResponse } from './models'
import { promptAction, router } from '@kit.ArkUI'const req = axios.create()@Entry
@Component
struct Index {@State bookList: iBookInfo[] = []onPageShow(): void {this.getBookList()}async getBookList() {try {let res: AxiosResponse<iBookResponse> =await req.request({url: 'https://hmajax.itheima.net/api/books',params: {creator: 'ivan'}})this.bookList = res.data.data} catch (err) {AlertDialog.show({ message: JSON.stringify(err, null, 2) })}}build() {Column() {// 1. 我的书架this.MyBook()// 2. 书籍列表this.BookList()}.height('100%').width('100%')}// 1. 我的书架@BuilderMyBook() {Row() {Image($r('app.media.ic_public_drawer_filled')).height(20)Text('我的书架').fontSize(20).fontWeight(800)Image($r('app.media.ic_public_add')).height(20).onClick(() => {router.pushUrl({ url: 'pages/axiosbooks/addBook' })})}.width('100%').justifyContent(FlexAlign.SpaceBetween).padding(10).border({ width: { bottom: 1 }, color: { bottom: 'rgba(0,0,0,0.2)' } })}// 2. 书籍列表@BuilderBookList() {List() {ForEach(this.bookList, (item: iBookInfo) => {ListItem() {// 布局Row({ space: 10 }) {Image($r('app.media.ic_public_cover')).width(100)Column({ space: 25 }) {Column() {Text('书名:' + item.bookname).width('100%').fontSize(20).fontWeight(800)Text('作者:' + item.author).width('100%').fontSize(14).fontWeight(600).fontColor('rgba(0,0,0,0.4)').padding({ top: 5 })}Text('出版社:' + item.publisher).width('100%').fontWeight(600).fontColor('rgba(0,0,0,0.4)')}.layoutWeight(1)}.padding(10).onClick(() => {router.pushUrl({ url: 'pages/axiosbooks/editBook', params: { bookid: item.id } })})}.swipeAction({end: this.delBuilder(item.id)})})}}// 3. 删除书籍的构建函数@BuilderdelBuilder(id: number) {Column() {Text('删除').backgroundColor(Color.Red).fontColor(Color.White).height('100%').width(60).textAlign(TextAlign.Center)}.padding(10).onClick(() => {promptAction.showDialog({title: '删除提示',message: '确认删除图书吗?',buttons: [{text: '取消',color: '#000'},{text: '确认',color: '#ff27a1d7'},]}).then(async res => {// res返回的内容:{index:0} 取消按钮被点击, {index:1} 确认按钮被点击// AlertDialog.show({ message: JSON.stringify(res, null, 2) })if (res.index == 1) {try {// 此处编写代码let res: AxiosResponse<iBookResponse> = await req.request({method: 'delete',url: 'https://hmajax.itheima.net/api/books/' + id})promptAction.showToast({ message: res.data.message })this.getBookList()} catch (err) {AlertDialog.show({ message: JSON.stringify(err, null, 2) })}}})})}
}

5.4. 编辑图书

5.4.1. 回显图书信息

// 导入创建者
import { creator, iBookInfoDetial } from './models'
import { router } from '@kit.ArkUI'
import axios, { AxiosResponse } from '@ohos/axios'interface iRouterParams {bookid: number
}const req = axios.create()@Entry
@Component
struct addPage {@State bookname: string = ''@State author: string = ''@State publisher: string = ''bookid: number = 0aboutToAppear(): void {let routerObj = router.getParams() as iRouterParamsthis.bookid = routerObj.bookidthis.loadBook()}// 1. 回显图书数据async loadBook() {try {// 此处编写代码let res: AxiosResponse<iBookInfoDetial> = await req.request({url: 'https://hmajax.itheima.net/api/books/' + this.bookid})this.bookname = res.data.data.booknamethis.author = res.data.data.authorthis.publisher = res.data.data.publisher} catch (err) {console.error('err--->', JSON.stringify(err).slice(0,800))}}build() {Navigation() {Column({ space: 10 }) {Row() {Text('图书名称:')TextInput({ placeholder: '请输入图书名字', text: $$this.bookname })}Row() {Text('图书作者:')TextInput({ placeholder: '请输入作者名字', text: $$this.author })}Row() {Text('图书出版社:')TextInput({ placeholder: '请输入出版社名字', text: $$this.publisher })}Button({ type: ButtonType.Normal }) {Text('保存').fontColor(Color.White).fontWeight(800)}.width('100%').height(40).borderRadius(8)}.height('100%').width('100%').padding(10)}.title('编辑  图书').titleMode(NavigationTitleMode.Mini)}
}

5.4.2. 修改图书信息

// 导入创建者
import { creator, iBookInfoDetial } from './models'
import { promptAction, router } from '@kit.ArkUI'
import axios, { AxiosResponse } from '@ohos/axios'
import { iReqeustBody } from './addBook'interface iRouterParams {bookid: number
}const req = axios.create()@Entry
@Component
struct addPage {@State bookname: string = ''@State author: string = ''@State publisher: string = ''bookid: number = 0aboutToAppear(): void {let routerObj = router.getParams() as iRouterParamsthis.bookid = routerObj.bookidthis.loadBook()}// 1. 回显图书数据async loadBook() {try {// 此处编写代码let res: AxiosResponse<iBookInfoDetial> = await req.request({url: 'https://hmajax.itheima.net/api/books/' + this.bookid})this.bookname = res.data.data.booknamethis.author = res.data.data.authorthis.publisher = res.data.data.publisher} catch (err) {console.error('err--->', JSON.stringify(err).slice(0, 800))}}// 2. 修改图书async saveBook() {try {// 此处编写代码let res: AxiosResponse<iBookInfoDetial> =await req.request<null, AxiosResponse<iBookInfoDetial>, iReqeustBody>({method: 'put',url: 'https://hmajax.itheima.net/api/books/' + this.bookid,data: {bookname: this.bookname,author: this.author,publisher: this.publisher,creator: creator}})promptAction.showToast({ message: res.data.message })router.back()} catch (err) {// console.log('编辑图书失败--->', JSON.stringify(err).slice(0, 800))AlertDialog.show({message:JSON.stringify(err,null,2)})}}build() {Navigation() {Column({ space: 10 }) {Row() {Text('图书名称:')TextInput({ placeholder: '请输入图书名字', text: $$this.bookname })}Row() {Text('图书作者:')TextInput({ placeholder: '请输入作者名字', text: $$this.author })}Row() {Text('图书出版社:')TextInput({ placeholder: '请输入出版社名字', text: $$this.publisher })}Button({ type: ButtonType.Normal }) {Text('保存').fontColor(Color.White).fontWeight(800)}.width('100%').height(40).borderRadius(8).onClick(()=>{this.saveBook()})}.height('100%').width('100%').padding(10)}.title('编辑  图书').titleMode(NavigationTitleMode.Mini)}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/71053.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【我的 PWN 学习手札】House of Husk

House of Husk House of Husk是利用格式化输出函数如printf、vprintf在打印输出时&#xff0c;会解析格式化字符如%x、%lld从而调用不同的格式化打印方法&#xff08;函数&#xff09;。同时C语言还提供了注册自定义格式化字符的方法。注册自定义格式化字符串输出方法&#xf…

【多模态】Magma多模态AI Agent

1. 前言 微软杨建伟团队&#xff0c;最近在AI Agent方面动作连连&#xff0c;前两天开源了OmniParser V2&#xff0c;2月26日又开源了Magma&#xff0c;OmniParser专注在对GUI的识别解析&#xff0c;而Magma则是基于多模态技术&#xff0c;能够同时应对GUI和物理世界的交互&…

Linux系统Pycharm界面卡死无法显示其他界面

1、使用如下代码查看Pycharm的进程 ps aux | grep pycharm2、使用kill关闭所有pycharm进程 kill -9 <替换为你进程的PID>不确定可以执行如下代码&#xff0c;直接全部关闭&#xff1a; pkill -9 -f pycharm3、如果界面还是存在并且仍然卡死 如果 pycharm 界面仍然显…

QT异步编程之线程池QThreadPool

一、概述 在一个应用程序中&#xff0c;我们需要多次使用线程&#xff0c;也就意味着&#xff0c;我们需要多次创建并销毁线程。而创建线程并销毁线程的过程势必会消耗内存。QThreadPool是Qt框架中用于管理线程池的类。它提供了一种高效的方式来管理和重用线程&#xff0c;从而…

算法仿真平台搭建1-FFMPEG+RtspSever快速搭建一个RTSP服务器

一、前言 本文相关的全部源码和RtspSever库&#xff0c;我已打包上传&#xff0c;欢迎大家免费下载&#xff0c;testRTSPSever。 每一个嵌入式视觉算法工程师&#xff0c;都应该有一套属于自己的算法仿真和测试环境。可以方便地进行视频、图像等素材进行在线导入&#xff0c;可…

盛京开源社区加入 GitCode,书写东北开源生态新篇章

在数字化转型与开源技术蓬勃发展的浪潮下&#xff0c;开源社区已成为推动技术创新的核心力量。盛京开源社区&#xff08;SJOSC&#xff09;作为沈阳地区的开源交流平台&#xff0c;始终致力于连接开发者、企业及高校&#xff0c;构建区域技术生态圈。 现在&#xff0c;盛京开源…

安装Git(小白也会装)

一、官网下载&#xff1a;Git 1.依次点击&#xff08;红框&#xff09; 不要安装在C盘了&#xff0c;要炸了&#xff01;&#xff01;&#xff01; 后面都 使用默认就好了&#xff0c;不用改&#xff0c;直接Next&#xff01; 直到这里&#xff0c;选第一个 这两种选项的区别如…

代码审计入门学习

简介 HadSky轻论坛程序为个人原创PHP系统&#xff0c;作者为蒲乐天&#xff0c;后端基于puyuetianPHP框架驱动&#xff0c;前端基于 puyuetianUI框架驱动&#xff0c;默认编辑器为puyuetianEditor富文本编辑器&#xff0c;其他非原创框架及驱动JQuery.js 及Font-Awesome字体库…

测试金蝶云的OpenAPI

如何使用Postman测试K3Cloud的OpenAPI 1. 引言 在本篇博客中&#xff0c;我将带你逐步了解如何使用Postman测试和使用K3Cloud的OpenAPI。内容包括下载所需的SDK文件、配置文件、API调用及测试等步骤。让我们开始吧&#xff01; 2. 下载所需的SDK文件 2.1 获取SDK 首先&…

服务端驱动UI架构解析:React Server Components与流式渲染的革命

引言&#xff1a;重新定义前后端边界 Shopify采用React Server Components后&#xff0c;动态模块加载速度提升340%&#xff0c;客户端Bundle减少62%。Discord重构消息流服务&#xff0c;通过流式渲染使首屏TTI从4.2s降至1.1s。Vercel生产数据显示&#xff0c;混合渲染技术让L…

绕过 RAG 实时检索瓶颈,缓存增强生成(CAG)如何助力性能突破?

编者按&#xff1a; 你是否曾经遇到过这样的困扰&#xff1a;在开发基于 RAG 的应用时&#xff0c;实时检索的延迟让用户体验大打折扣&#xff1f;或者在处理复杂查询时&#xff0c;检索结果的不准确导致回答质量不尽如人意&#xff1f; 在当前大语言模型应用大规模落地的背景下…

基于django图书信息管理系统的搭建(增删改查)

✍django项目搭建教程 ☞ ----------------- 教程 本文主要讲解django如何连接数据库MySQL并且可视化展示&#xff0c;实现增删改查功能 目录 一. 创建django应用 二. 数据库配置 三. 查看数据库 四. 编写代码 4.1视图函数 4.2 配置URL 4.3创建模板文件 4.…

鸿蒙NEXT开发-元服务和服务卡片的开发

注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章写的好的话&#xff0c;可以点下关注&#xff0c;博主会一直更新鸿蒙next相关知识 目录 1. 元服务基本概念 1.1 基本介绍 1.2 元…

HBuilder X中,uni-app、js的延时操作及定时器

完整源码下载 https://download.csdn.net/download/luckyext/90430165 在HBuilder X中&#xff0c;uni-app、js的延时操作及定时器可以用setTimeout和setInterval这两个函数来实现。 1.setTimeout函数用于在指定的毫秒数后执行一次函数。 例如&#xff0c; 2秒后弹出一个提…

IP属地是通过卫星定位的吗?如何保护用户隐私

在数字时代&#xff0c;网络空间成为了人们日常生活不可或缺的一部分。随着社交媒体、在线服务等平台的兴起&#xff0c;用户IP属地信息的重要性日益凸显。然而&#xff0c;关于IP属地是如何确定的&#xff0c;尤其是是否通过卫星定位这一问题&#xff0c;却常常引发公众的疑问…

华为云之使用鲲鹏弹性云服务器部署Node.js环境【玩转华为云】

华为云之使用鲲鹏弹性云服务器部署Node.js环境【玩转华为云】 一、本次实践介绍1.1 实践环境简介1.3 本次实践完成目标 二、 相关服务介绍2.1 华为云ECS云服务器介绍2.2 Node.js介绍 三、环境准备工作3.1 预置实验环境3.2 查看预置环境信息 四、登录华为云4.1 登录华为云4.2 查…

PyCharm中通过命令行执行`pip`命令下载到哪里了:虚拟环境目录下

PyCharm中通过命令行执行pip命令下载到哪里了:虚拟环境目录下 在PyCharm中通过命令行执行pip命令安装工具包,包的下载位置取决于多种因素 虚拟环境 如果项目使用了虚拟环境(通常是推荐的做法): Windows:虚拟环境通常位于项目目录下的.venv文件夹(默认情况)或你指定…

flink系列之:使用flink cdc3从mysql数据库同步数据到doris和starrocks

flink系列之&#xff1a;使用flink cdc3从mysql数据库同步数据到doris和starrocks 一、下载部署flink二、下载部署flink cdc3三、下载mysql-connector-java到flink和flink cdc的lib目录四、flink设置checkpoint支持增量同步数据五、mysql到doris和starrocks的yaml配置文件六、启…

java后端开发day23--面向对象进阶(四)--抽象类、接口、内部类

&#xff08;以下内容全部来自上述课程&#xff09; 1.抽象类 父类定义抽象方法后&#xff0c;子类的方法就必须重写&#xff0c;抽象方法在的类就是抽象类。 1.定义 抽象方法 将共性的行为&#xff08;方法&#xff09;抽取到父类之后。由于每一个子类执行的内容是不一样…

第48天:Web开发-JavaEE应用依赖项Log4j日志Shiro验证FastJson数据XStream格式

#知识点 1、安全开发-JavaEE-第三方依赖开发安全 2、安全开发-JavaEE-数据转换&FastJson&XStream 3、安全开发-JavaEE-Shiro身份验证&Log4j日志处理 一、Log4j 一个基于Java的日志记录工具&#xff0c;当前被广泛应用于业务系统开发&#xff0c;开发者可以利用该工…