
简体中文
发起网络请求。
Web | 微信小程序 | Android | iOS | iOS uni-app x UTS 插件 | HarmonyOS |
---|---|---|---|---|---|
4.0 | 4.41 | 3.91 | 4.11 | 4.11 | 4.61 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
param | RequestOptions<T> | 是 | - | - | 网络请求参数 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
data | T | 否 | - | 开发者服务器返回的数据, app-android平台从 4.51版本开始支持ArrayBuffer, app-ios平台从 4.61版本开始支持ArrayBuffer | |
statusCode | number | 是 | - | 开发者服务器返回的 HTTP 状态码 | |
header | any | 是 | - | 开发者服务器返回的 HTTP Response Header | |
cookies | Array<string> | 是 | - | 开发者服务器返回的 cookies,格式为字符串数组 |
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
errCode | number | 是 | - | - | 错误码 | ||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||
errSubject | string | 是 | - | - | 统一错误主题(模块)名称 | ||||||||||||||||||||||||||||||
data | any | 否 | - | - | 错误信息中包含的数据 | ||||||||||||||||||||||||||||||
cause | Error | 否 | - | - | 源错误信息,可以包含多个错误,详见SourceError | ||||||||||||||||||||||||||||||
errMsg | string | 是 | - | - |
类型 |
---|
RequestTask |
abort 中断网络请求。
Web | 微信小程序 | Android | iOS | iOS uni-app x UTS 插件 | HarmonyOS |
---|---|---|---|---|---|
4.0 | 4.41 | 3.91 | 4.11 | 4.11 | 4.61 |
onChunkReceived 监听 Transfer-Encoding Chunk Received 事件。
Web | 微信小程序 | Android | iOS | iOS uni-app x UTS 插件 | HarmonyOS | HarmonyOS uni-app x UTS 插件 |
---|---|---|---|---|---|---|
4.71 | 4.41 | 4.71 | 4.71 | 4.71 | 4.71 | 4.71 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
listener | (result: RequestTaskOnChunkReceivedListenerResult) => void | 是 | - | - |
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
data | ArrayBuffer | 是 | - | 返回的chunk buffer |
类型 |
---|
number |
offChunkReceived 移除 Transfer-Encoding Chunk Received 事件的监听函数。
Web | 微信小程序 | Android | iOS | iOS uni-app x UTS 插件 | HarmonyOS | HarmonyOS uni-app x UTS 插件 |
---|---|---|---|---|---|---|
4.71 | 4.41 | 4.71 | 4.71 | 4.71 | 4.71 | 4.71 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
listener | number | (result: RequestTaskOnChunkReceivedListenerResult) => void | 否 | - | - |
onHeadersReceived 监听 HTTP Response Header 事件。
Web | 微信小程序 | Android | iOS | iOS uni-app x UTS 插件 | HarmonyOS | HarmonyOS uni-app x UTS 插件 |
---|---|---|---|---|---|---|
4.71 | 4.41 | 4.71 | 4.71 | 4.71 | 4.71 | 4.71 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
listener | (result: RequestTaskOnHeadersReceivedListenerResult) => void | 是 | - | - | HTTP Response Header 事件的监听函数 |
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
cookies | Array<string> | 是 | - | 开发者服务器返回的 cookies,格式为字符串数组 | |
header | UTSJSONObject | 是 | - | 开发者服务器返回的 HTTP Response Header | |
statusCode | number | 是 | - | 开发者服务器返回的 HTTP 状态码 (目前开发者工具上不会返回 statusCode 字段,可用真机查看该字段,后续将会支持) |
类型 |
---|
number |
offHeadersReceived 移除 HTTP Response Header 事件的监听函数。
Web | 微信小程序 | Android | iOS | iOS uni-app x UTS 插件 | HarmonyOS | HarmonyOS uni-app x UTS 插件 |
---|---|---|---|---|---|---|
4.71 | 4.41 | 4.71 | 4.71 | 4.71 | 4.71 | 4.71 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
listener | number | (result: RequestTaskOnHeadersReceivedListenerResult) => void | 否 | - | - |
示例为hello uni-app x alpha分支,与最新HBuilderX Alpha版同步。与最新正式版同步的master分支示例另见
示例
<template>
<view style="flex: 1;">
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-common-mt" style="border-width: 2px;border-style: solid; border-radius: 4px;">
<textarea :value="res" class="uni-textarea" style="width: 100%"></textarea>
</view>
<view>
<text>地址 : {{ host + url}}</text>
<text>请求方式 : {{method}}</text>
</view>
<view class="uni-btn-v uni-common-mt">
<button type="primary" @click="sendRequest">发起请求</button>
</view>
</view>
<scroll-view style="flex: 1;" show-scrollbar="true">
<view style="padding: 20px;">
<text>设置请求方式</text>
<view class="uni-common-pb"></view>
<view style="flex-direction: row;flex-wrap: wrap;">
<button style="padding: 5px; margin-right: 10px;" type="primary" size="mini"
@click="changeMethod('GET')">GET</button>
<button style="padding: 5px; margin-right: 10px; " type="primary" size="mini"
@click="changeMethod('POST')">POST</button>
<button style="padding: 5px; margin-right: 10px; " type="primary" size="mini"
@click="changeMethod('PUT')">PUT</button>
<button style="padding: 5px; margin-right: 10px;" type="primary" size="mini"
@click="changeMethod('DELETE')">DELETE</button>
<button style="padding: 5px; margin-right: 10px; " type="primary" size="mini"
@click="changeMethod('PATCH')">PATCH</button>
<button style="padding: 5px;margin-right: 10px;" type="primary" size="mini"
@click="changeMethod('OPTIONS')">OPTIONS</button>
<button style="padding: 5px;" type="primary" size="mini" @click="changeMethod('HEAD')">HEAD</button>
</view>
</view>
<view style="padding: 20px;">
<text>请求返回错误码的接口(默认为GET)</text>
<view class="uni-common-pb"></view>
<view style="flex-direction: row;flex-wrap: wrap;">
<button style="padding: 5px;" type="primary" size="mini" v-for="(item, index) in errorCodeUrls" :key="index"
@click="changeUrl(item)">{{item}}</button>
</view>
</view>
<view style="padding: 20px;">
<text>请求不同header的接口(默认为GET)</text>
<view class="uni-common-pb"></view>
<view style="flex-direction: row;flex-wrap: wrap;">
<button style="padding: 5px;" type="primary" size="mini" v-for="(item, index) in headerUrls" :key="index"
@click="changeUrl(item)">{{item}}</button>
</view>
</view>
<view style="padding: 20px;">
<text>请求不同content-type的接口(默认为GET)</text>
<view class="uni-common-pb"></view>
<view style="flex-direction: row;flex-wrap: wrap;">
<button style="padding: 5px;" type="primary" size="mini" v-for="(item, index) in contentTypeUrls" :key="index"
@click="changeUrl(item)">{{item}}</button>
</view>
</view>
<view style="padding: 20px;">
<text>POST请求(有body)</text>
<view class="uni-common-pb"></view>
<view style="flex-direction: row;flex-wrap: wrap;">
<button style="padding: 5px;" type="primary" size="mini" v-for="(item, index) in postUrls" :key="index"
@click="changeUrlFromPost(item)">{{item}}</button>
</view>
</view>
<!-- #ifdef APP || MP-WEIXIN || WEB -->
<view style="padding: 20px;">
<text>ArrayBuffer 测试</text>
<view class="uni-common-pb"></view>
<view style="flex-direction: row;flex-wrap: wrap;">
<button style="padding: 5px;" type="primary" size="mini"
@click="sendArrayBuffer(false)">请求body为ArrayBuffer,response也为ArrayBuffer</button>
<button style="padding: 5px;" type="primary" size="mini"
@click="sendArrayBuffer(true)">请求response为ArrayBuffer</button>
</view>
</view>
<!-- #endif -->
<view style="padding: 20px;">
<text>RequestTask 测试</text>
<view class="uni-common-pb"></view>
<button type="primary" @click="sendChunkRequest">流式请求</button>
</view>
<view class="uni-common-pb"></view>
<view class="uni-common-pb"></view>
</scroll-view>
</view>
</template>
<script>
// #ifdef APP-ANDROID || APP-IOS || APP-HARMONY
import {
testInovkeRequest,
CommonOptions
} from '@/uni_modules/test-invoke-network-api'
// #endif
class GETDataType {
data : UTSJSONObject | null = null
}
const duration = 2000
const methodMap = {
"GET": "/api/http/method/get",
"POST": "/api/http/method/post",
"PUT": "/api/http/method/put",
"DELETE": "/api/http/method/delete",
"PATCH": "/api/http/method/patch",
"OPTIONS": "/api/http/method/options",
"HEAD": "/api/http/method/head"
}
export default {
data() {
return {
title: 'request',
res: '',
task: null as RequestTask | null,
host: "https://request.dcloud.net.cn",
url: "/api/http/method/get",
method: "GET" as RequestMethod | null,
data: null as any | null,
header: null as UTSJSONObject | null,
errorCodeUrls: [
"/api/http/statusCode/200",
"/api/http/statusCode/204",
"/api/http/statusCode/301",
"/api/http/statusCode/302",
"/api/http/statusCode/307",
"/api/http/statusCode/400",
"/api/http/statusCode/401",
"/api/http/statusCode/403",
"/api/http/statusCode/404",
"/api/http/statusCode/405",
"/api/http/statusCode/500",
"/api/http/statusCode/502",
"/api/http/statusCode/503",
"/api/http/statusCode/504",
],
headerUrls: [
"/api/http/header/ua",
"/api/http/header/referer",
"/api/http/header/requestCookie",
"/api/http/header/setCookie",
"/api/http/header/deleteCookie"
],
contentTypeUrls: [
"/api/http/contentType/text/plain",
"/api/http/contentType/text/html",
"/api/http/contentType/text/xml",
"/api/http/contentType/image/gif",
"/api/http/contentType/image/jpeg",
"/api/http/contentType/image/png",
"/api/http/contentType/application/json",
"/api/http/contentType/application/octetStream",
],
postUrls: [
"/api/http/contentType/json",
"/api/http/contentType/xWwwFormUrlencoded",
],
//自动化测试例专用
jest_requestTask_result: false,
jest_result: false,
jest_result_data: ""
}
},
onUnload() {
uni.hideLoading();
this.task?.abort();
},
methods: {
sendChunkRequest() {
uni.navigateTo({
url: "/pages/API/request/requestTask"
})
},
changeMethod(e : RequestMethod) {
this.method = e;
this.url = methodMap[e] as string;
this.data = null;
this.header = null;
},
changeUrl(e : string) {
this.method = "GET";
this.url = e;
this.data = null;
this.header = null;
},
changeUrlFromPost(e : string) {
this.method = "POST";
this.url = e;
switch (e) {
case "/api/http/contentType/json":
this.header = {
"Content-Type": "application/json"
};
this.data = {
"hello": "world"
};
break;
case "/api/http/contentType/xWwwFormUrlencoded":
this.header = {
"Content-Type": "application/x-www-form-urlencoded"
};
this.data = "hello=world";
break;
}
},
// #ifdef APP | MP-WEIXIN | WEB
sendArrayBuffer(onlyResponse : boolean) {
this.method = "POST"
this.url = "/api/http/contentType/arrayBuffer/post"
if (onlyResponse) {
this.header = {
"Content-Type": "application/json"
};
this.data = {
"hello": "world"
};
uni.showLoading({
title: "请求中..."
})
this.task = uni.request<ArrayBuffer>({
url: this.host + this.url,
method: this.method,
data: this.data,
header: this.header,
timeout: 60000,
sslVerify: false,
withCredentials: false,
responseType: 'arraybuffer',
firstIpv4: false,
success: (res) => {
if (res.data != null) {
let uint8 = new Uint8Array(res.data as ArrayBuffer)
console.log('request success', uint8.toString())
this.res = '请求结果 : ' + uint8.toString()
console.log('request success header is :', JSON.stringify(res.header))
uni.showToast({
title: '请求成功',
icon: 'success',
mask: true,
duration: duration
});
} else {
uni.showModal({
content: 'error',
showCancel: false
});
}
},
fail: (err) => {
console.log('request fail', err);
uni.showModal({
content: err.errMsg,
showCancel: false
});
},
complete: () => {
uni.hideLoading()
this.task = null
},
});
} else {
uni.chooseImage({
count: 1,
albumMode: "system",
sizeType: ["original"],
sourceType: ["album"],
success: (e) => {
console.log(e.tempFilePaths[0]);
uni.getFileSystemManager().readFile({
filePath: e.tempFilePaths[0],
success: (res) => {
this.data = res.data as ArrayBuffer
this.header = {
"Content-Type": "application/octet-stream"
};
uni.showLoading({
title: "请求中..."
})
this.task = uni.request<ArrayBuffer>({
url: this.host + this.url,
method: this.method,
data: this.data,
header: this.header,
timeout: 60000,
sslVerify: false,
withCredentials: false,
firstIpv4: false,
responseType: 'arraybuffer',
success: (res) => {
console.log()
if (res.data != null) {
uni.showToast({
title: '请求成功',
icon: 'success',
mask: true,
duration: duration
});
this.res = '请求结果 : byteLength=' + (res.data as ArrayBuffer).byteLength
console.log('request success header is :', JSON.stringify(res.header))
} else {
uni.showModal({
content: 'error',
showCancel: false
});
}
},
fail: (err) => {
console.log('request fail', err);
uni.showModal({
content: err.errMsg,
showCancel: false
});
},
complete: () => {
uni.hideLoading()
this.task = null
},
});
}
})
}
});
}
},
// #endif
sendRequest() {
uni.showLoading({
title: "请求中..."
})
this.task = uni.request({
url: this.host + this.url,
// dataType: "json",
// responseType: "json",
method: this.method,
data: this.data,
header: this.header,
timeout: 6000,
sslVerify: false,
withCredentials: false,
firstIpv4: false,
success: (res) => {
console.log('request success', JSON.stringify(res.data))
console.log('request success header is :', JSON.stringify(res.header))
uni.showToast({
title: '请求成功',
icon: 'success',
mask: true,
duration: duration
});
this.res = '请求结果 : ' + JSON.stringify(res);
},
fail: (err) => {
console.log('request fail', err);
uni.showModal({
content: err.errMsg,
showCancel: false
});
},
complete: () => {
uni.hideLoading()
this.task = null
},
});
},
//自动化测试例专用
jest_request() {
uni.request({
url: this.host + this.url,
// dataType: "json",
// responseType: "json",
method: this.method,
data: this.data,
header: this.header,
timeout: 6000,
sslVerify: false,
withCredentials: false,
firstIpv4: false,
success: () => {
this.jest_result = true;
},
fail: () => {
this.jest_result = false;
},
});
},
jest_set_cookie() {
uni.request({
url: this.host + "/api/http/header/setCookie",
method: "GET",
timeout: 6000,
sslVerify: false,
withCredentials: false,
firstIpv4: false,
success: () => {
this.jest_cookie_request(true)
},
fail: () => {
this.jest_result = false;
},
});
},
jest_set_cookie_expires() {
uni.request({
url: this.host + "/api/http/header/setCookie?expires=5",
method: "GET",
timeout: 6000,
sslVerify: false,
withCredentials: false,
firstIpv4: false,
success: () => {
this.jest_cookie_request(true)
},
fail: () => {
this.jest_result = false;
},
});
},
jest_delete_cookie() {
uni.request({
url: this.host + "/api/http/header/deleteCookie",
method: "GET",
timeout: 6000,
sslVerify: false,
withCredentials: false,
firstIpv4: false,
success: () => {
this.jest_cookie_request(false)
},
fail: () => {
this.jest_result = false;
},
});
},
jest_cookie_request(needCookie : boolean) {
uni.request({
url: this.host + "/api/http/header/requestCookie",
method: "GET",
timeout: 6000,
sslVerify: false,
withCredentials: false,
firstIpv4: false,
success: (res) => {
const requestCookie = (res.data as UTSJSONObject).getJSON("data")?.getAny("requestCookie")
this.jest_result_data = JSON.stringify(requestCookie)
if (requestCookie instanceof Array) {
this.jest_result = needCookie ? requestCookie.length > 0 : requestCookie.length == 0
} else {
this.jest_result = needCookie ? (requestCookie as UTSJSONObject).toMap().size > 0 : (requestCookie as UTSJSONObject).toMap().size == 0
}
},
fail: () => {
this.jest_result = false;
},
});
},
jest_timeout_null() {
uni.request({
url: this.host + (methodMap['GET'] as string),
method: "GET",
timeout: null,
sslVerify: false,
withCredentials: false,
firstIpv4: false,
success: () => {
this.jest_result = true;
},
fail: () => {
this.jest_result = false;
},
});
},
jest_get_with_data() {
uni.request({
url: "https://unidemo.dcloud.net.cn/api/banner/36kr",
method: "GET",
data: {
column: 'id,post_id,title,author_name,cover,published_at' //需要的字段名
},
timeout: 6000,
sslVerify: false,
withCredentials: false,
firstIpv4: false,
success: () => {
this.jest_result = true;
},
fail: () => {
this.jest_result = false;
},
});
},
jest_get_with_generics() {
uni.request<GETDataType>({
url: this.host + (methodMap['GET'] as string),
method: "GET",
timeout: null,
sslVerify: false,
withCredentials: false,
firstIpv4: false,
success: (res : RequestSuccess<GETDataType>) => {
this.jest_result = true;
},
fail: () => {
this.jest_result = false;
},
});
},
jest_get_array() {
uni.request<UTSJSONObject[]>({
url: 'https://unidemo.dcloud.net.cn/api/news?column=title,author_name,cover,published_at',
method: "GET",
success: (res : RequestSuccess<UTSJSONObject[]>) => {
if (res.statusCode == 200 && Array.isArray(res.data)) {
this.jest_result = true
} else {
this.jest_result = false
}
},
fail: () => {
this.jest_result = false
}
});
},
jest_uts_module_invoked() {
// #ifdef APP-ANDROID || APP-IOS || APP-HARMONY
this.jest_result = false
testInovkeRequest({
success: (res : any) => {
this.jest_result = true
},
fail: (err : any) => {
this.jest_result = false
}
} as CommonOptions)
// #endif
},
jest_respone_json_string() {
uni.request({
url: "https://request.dcloud.net.cn/api/http/contentType/text/json",
success: (res : RequestSuccess<any>) => {
this.jest_result = typeof res.data == "object"
},
fail: (e : RequestFail) => {
this.jest_result = false
}
})
},
jest_respone_with_string_generics() {
uni.request<string>({
url: this.host + (methodMap['GET'] as string),
method: "GET",
timeout: null,
sslVerify: false,
withCredentials: false,
firstIpv4: false,
success: (res : RequestSuccess<string>) => {
this.jest_result = true;
},
fail: () => {
this.jest_result = false;
},
});
},
jest_respone_with_404_and_string_generics() {
uni.request<string>({
url: this.host + "/api/http/statusCode/404",
method: "GET",
timeout: null,
sslVerify: false,
withCredentials: false,
firstIpv4: false,
success: (res : RequestSuccess<string>) => {
this.jest_result = true;
},
fail: () => {
this.jest_result = false;
},
});
}
}
}
</script>
<style>
.uni-textarea {
padding: 9px;
font-size: 14px;
}
</style>
uni.request
、uni.uploadFile
、uni.downloadFile
等网络API之间支持共享cookie Cookie共享介绍。AI大语言模型的服务器,向客户端持续的流式输出AI推理的结果文本。在客户端表现为打字机效果。
在uni-app x中,实现AI聊天的方式如下:
实现AI聊天的工作较为复杂,流式接收和渲染markdown很容易引发性能问题,处理原生的markdown解析工作量也很大。 所以DCloud提供了开源的uni-ai x,已完整实现原生的、全端的AI聊天,详见
由于uni-app x的强类型,导致联网获取JSON,拿到的不是js的object。
默认返回的是UTSJSONObject,UTSJSONObject是UTS提供的JSON数据对象,实现了js的object的JSON相关功能,但又有区别。如果照搬js的object用法会失败。
同时request也支持泛型,返回一个开发者自定义的type。
请不熟悉强类型的开发者务必阅读教程:uni-app x的联网教程
const options: RequestOptions<Person> = ...
uni.request<Person>(options)
complete
回调中置空Task对象,例complete: () => {
this.task = null
},
如不释放,在调用Task对象的方法将导致控制台报错:
error: instance object does not exist: id:15
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
errMsg | string | 是 | - | 错误信息 |