簡介
[Axios] ,是一個基于 promise 的網絡請求庫,可以運行 node.js 和瀏覽器中。本庫基于[Axios]原庫v1.3.4版本進行適配,使其可以運行在 OpenHarmony,并沿用其現有用法和特性。
- http 請求
- Promise API
- request 和 response 攔截器
- 轉換 request 和 response 的 data 數據
- 自動轉換 JSON data 數據
下載安裝
ohpm install @ohos/axios
需要權限
ohos.permission.INTERNET
接口和屬性列表
接口列表
接口 | 參數 | 功能 |
---|---|---|
axios(config) | [config]:請求配置 | 發送請求 |
axios.create(config) | [config]:請求配置 | 創建實例 |
axios.request(config) | [config]:請求配置 | 發送請求 |
axios.get(url[, config]) | url:請求地址 [config]:請求配置 | 發送get請求 |
axios.delete(url[, config]) | url:請求地址 [config]:請求配置 | 發送delete請求 |
axios.post(url[, data[, config]]) | url:請求地址 data:發送請求體數據 [config]:請求配置 | 發送post請求 |
axios.put(url[, data[, config]]) | url:請求地址 data:發送請求體數據 [config]:請求配置 | 發送put請求 |
屬性列表
屬性 | 描述 |
---|---|
axios.defaults['xxx'] | 默認設置 。值為請求配置 [config] 中的配置項 例如 axios.defaults.headers 獲取頭部信息 |
axios.interceptors | 攔截器。參考 [攔截器] 的使用 |
使用示例
使用前在demo中entry-->src-->main-->ets-->common-->Common.ets文件中改為正確的服務器地址,在entry-->src-->main-->resources-->rawfile目錄下添加正確的證書,才可正常的使用demo。
發起一個 GET 請求
axios支持泛型參數,由于ArkTS不再支持any類型,需指定參數的具體類型。 如:axios.get(url)
- T: 是響應數據類型。當發送一個 POST 請求時,客戶端可能會收到一個 JSON 對象。T 就是這個 JSON 對象的類型。默認情況下,T 是 any,這意味著可以接收任何類型的數據。
- R: 是響應體的類型。當服務器返回一個響應時,響應體通常是一個 JSON 對象。R 就是這個 JSON 對象的類型。默認情況下,R 是 AxiosResponse,這意味著響應體是一個 AxiosResponse 對象,它的 data 屬性是 T 類型的
- D: 是請求參數的類型。當發送一個 GET 請求時,可能會在 URL 中添加一些查詢參數。D 就是這些查詢參數的類型。參數為空情況下,D 是 null類型。
import axios from '@ohos/axios'
interface userInfo{
id: number
name: string,
phone: number
}
// 向給定ID的用戶發起請求
axios.get< userInfo, AxiosResponse< userInfo >, null >('/user?ID=12345')
.then((response: AxiosResponse< userInfo >)= > {
// 處理成功情況
console.info("id" + response.data.id)
console.info(JSON.stringify(response));
})
.catch((error: AxiosError)= > {
// 處理錯誤情況
console.info(JSON.stringify(error));
})
.then(()= > {
// 總是會執行
});
// 上述請求也可以按以下方式完成(可選)
axios.get< userInfo, AxiosResponse< userInfo >, null >('/user', {
params: {
ID: 12345
}
})
.then((response:AxiosResponse< userInfo >) = > {
console.info("id" + response.data.id)
console.info(JSON.stringify(response));
})
.catch((error:AxiosError) = > {
console.info(JSON.stringify(error));
})
.then(() = > {
// 總是會執行
});
// 支持async/await用法
async function getUser() {
try {
const response:AxiosResponse = await axios.get< string, AxiosResponse< string >, null >(this.getUrl);
console.log(JSON.stringify(response));
} catch (error) {
console.error(JSON.stringify(error));
}
}
發送一個 POST 請求
interface user {
firstName: string,
lastName: string
}
axios.post< string, AxiosResponse< string >, user >('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then((response: AxiosResponse< string >) = > {
console.info(JSON.stringify(response));
})
.catch((error) = > {
console.info(JSON.stringify(error));
});
發起多個并發請求
const getUserAccount = ():Promise< AxiosResponse > = > {
return axios.get< string, AxiosResponse< string >, null >('/user/12345');
}
const getUserPermissions = ():Promise< AxiosResponse > = > {
return axios.get< string, AxiosResponse< string >, null >('/user/12345/permissions');
}
Promise.all< AxiosResponse >([getUserAccount(), getUserPermissions()])
.then((results:AxiosResponse[]) = > {
const acct = results[0].data as string;
const perm = results[1].data as string;
});
使用說明
axios API
通過向 axios 傳遞相關配置來創建請求
axios(config)
// 發送一個get請求
axios< string, AxiosResponse< string >, null >({
method: "get",
url: 'https://www.xxx.com/info'
}).then((res: AxiosResponse) = > {
console.info('result:' + JSON.stringify(res.data));
}).catch((error: AxiosError) = > {
console.error(error.message);
})
axios(url[, config])
// 發送一個get請求(默認請求方式)
axios.get< string, AxiosResponse< string >, null >('https://www.xxx.com/info', { params: { key: "value" } })
.then((response: AxiosResponse) = > {
console.info("result:" + JSON.stringify(response.data));
})
.catch((error: AxiosError) = > {
console.error("result:" + error.message);
});
請求方法的 別名方式 來創建請求
為方便起見,為所有支持的請求方法提供了別名。
- axios.request(config)
- axios.get(url[, config])
- axios.delete(url[, config])
- axios.post(url[, data[, config]])
- axios.put(url[, data[, config]])
注意: 在使用別名方法時, url、method、data 這些屬性都不必在配置中指定。
// 發送get請求
axios.get< string, AxiosResponse< string >, null >('https://www.xxx.com/info', { params: { key: "value" } })
.then((response: AxiosResponse) = > {
console.info("result:" + JSON.stringify(response.data));
})
.catch((error: AxiosError) = > {
console.error("result:" + error.message);
});
axios 實例
創建一個實例
您可以使用自定義配置新建一個實例。
axios.create([config])
const instance = axios.create({
baseURL: 'https://www.xxx.com/info',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
實例方法
- axios#request(config)
- axios#get(url[, config])
- axios#delete(url[, config])
- axios#post(url[, data[, config]])
- axios#put(url[, data[, config]])
)請求配置
這些是創建請求時可以用的配置選項。只有 url 是必需的。如果沒有指定 method,請求將默認使用 get 方法。
{
// `url` 是用于請求的服務器 URL
url: '/user',
// `method` 是創建請求時使用的方法 支持post/get/put/delete方法,不區分大小寫,默認為get方法
method: 'get', // default
// `baseURL` 將自動加在 `url` 前面,除非 `url` 是一個絕對 URL。
// 它可以通過設置一個 `baseURL` 便于為 axios 實例的方法傳遞相對 URL
baseURL: 'https://www.xxx.com/info',
// `transformRequest` 允許在向服務器發送前,修改請求數據
// 它只能用于 'PUT', 'POST' 和 'PATCH' 這幾個請求方法
// 數組中最后一個函數必須返回一個字符串, 一個Buffer實例,ArrayBuffer,FormData,或 Stream
// 你可以修改請求頭。
transformRequest: [function (data, headers) {
// 對發送的 data 進行任意轉換處理
return data;
}],
// `transformResponse` 在傳遞給 then/catch 前,允許修改響應數據
transformResponse: [function (data) {
// 對接收的 data 進行任意轉換處理
return data;
}],
// `headers` 是即將被發送的自定義請求頭
headers: {'Content-Type': 'application/json'},
// `params` 是即將與請求一起發送的 URL 參數
// 必須是一個無格式對象(plain object),其他對象如 URLSearchParams ,必須使用 paramsSerializer 進行序列化
params: {
ID: 12345
},
// `paramsSerializer` 是一個負責 `params` 序列化的函數
paramsSerializer: function(params) {
return params
},
// `data` 是作為請求主體被發送的數據
// 只適用于這些請求方法 'PUT', 'POST', 和 'PATCH'
// 在沒有設置 `transformRequest` 時,必須是以下類型之一,其他類型使用 transformRequest 轉換處理
// - string, plain object, ArrayBuffer
data: {
firstName: 'Fred'
},
// 發送請求體數據的可選語法
// 請求方式 post
// 只有 value 會被發送,key 則不會
data: 'Country=Brasil&City=Belo Horizonte',
// `timeout` 指定請求超時的毫秒數(0 表示無超時時間)
// 如果請求超過 `timeout` 的時間,請求將被中斷
timeout: 1000,
// `adapter` 允許自定義處理請求,這使測試更加容易。
// 返回一個 promise 并提供一個有效的響應 (參見 lib/adapters/README.md)。
adapter: function (config) {
/* ... */
},
// 如果設置了此參數,系統將使用用戶指定路徑的CA證書,(開發者需保證該路徑下CA證書的可訪問性),否則將使用系統預設CA證書,系統預設CA證書位置:/etc/ssl/certs/cacert.pem。證書路徑為沙箱映射路徑(開發者可通過Global.getContext().filesDir獲取應用沙箱路徑)。
caPath: '',
// 客戶端證書的clientCert字段,包括4個屬性:
// 客戶端證書(cert)、客戶端證書類型(certType)、證書私鑰(key)和密碼短語(keyPasswd)。
clientCert:{
certPath: '', // 客戶端證書路徑
certType: '', // 客戶端證書類型,包括pem、der、p12三種
keyPath: '', // 證書私鑰路徑
keyPasswd: '' // 密碼短語
}
// 優先級,范圍[1,1000],默認是1,值越大,優先級越高;
priority: 1,
// `responseType` 指定返回數據的類型,默認無此字段。如果設置了此參數,系統將優先返回指定的類型。
// 選項包括: string:字符串類型; object:對象類型; array_buffer:二進制數組類型。
responseType: 'string',
// `proxy`
// 是否使用HTTP代理,默認為false,不使用代理。
// 當proxy為AxiosProxyConfig類型時,使用指定網絡代理。
proxy: {
host: 'xx', // Host port
port: xx, // Host port
exclusionList: [] // Do not use a blocking list for proxy servers
}
// `onUploadProgress` 允許為上傳處理進度事件
onUploadProgress: function (progressEvent) {
// 對原生進度事件的處理
},
// `onDownloadProgress` 允許為下載處理進度事件,下載文件必須設置該事件
onDownloadProgress: function (progressEvent) {
// 對原生進度事件的處理
},
// 基于應用程序的上下文,只適用于上傳/下載請求
context: context,
// 下載路徑。此參數,只適用于下載請求,
// Stage模型下使用AbilityContext 類獲取文件路徑,比如:'${getContext(this).cacheDir}/test.txt’并將文件存儲在此路徑下
filePath: context,
}
響應結構
一個請求的響應包含以下信息。
{
// `data` 由服務器提供的響應
data: {},
// `status` 來自服務器響應的 HTTP 狀態碼
status: 200,
// `statusText` 來自服務器響應的 HTTP 狀態信息
statusText: 'OK',
// `headers` 是服務器響應頭
// 所有的 header 名稱都是小寫,而且可以使用方括號語法訪問
// 例如: `response.headers['content-type']`
headers: {},
// `config` 是 `axios` 請求的配置信息
config: {},
// `request` 是生成此響應的請求
request: {}
}
當使用 then 時,您將接收如下響應:
axios.get< string, AxiosResponse< string >, null >(this.getUrl)
.then( (response:AxiosResponse< string >)= > {
console.log("result data: " + response.data);
console.log("result status: " + response.status);
console.log("result statusText: " + response.statusText);
console.log("result headers: " + response.headers);
console.log("result config: " + response.config);
});
默認配置
您可以指定默認配置,它將作用于每個請求。
全局 axios 默認值
axios.defaults.baseURL = 'https://www.xxx.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
自定義實例默認值
// 創建實例時配置默認值
const instance = axios.create({
baseURL: 'https://www.xxx.com'
});
// 創建實例后修改默認值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
配置的優先級 配置將會按優先級進行合并。它的順序是:在lib/defaults.js中找到的庫默認值,然后是實例的 defaults 屬性,最后是請求的 config 參數。后面的優先級要高于前面的。下面有一個例子。
// 使用庫提供的默認配置創建實例
// 此時超時配置的默認值是 `0`
const instance = axios.create();
// 重寫庫的超時默認值
// 現在,所有使用此實例的請求都將等待2.5秒,然后才會超時
instance.defaults.timeout = 2500;
// 重寫此請求的超時時間,因為該請求需要很長時間
instance.get< string, AxiosResponse< string >, null >(this.getUrl, {
timeout: 5000
})
攔截器
在請求或響應被 then 或 catch 處理前攔截它們。
// 添加請求攔截器
axios.interceptors.request.use((config:InternalAxiosRequestConfig) = > {
// 對請求數據做點什么
return config;
}, (error:AxiosError) = > {
// 對請求錯誤做些什么
return Promise.reject(error);
});
// 添加響應攔截器
axios.interceptors.response.use((response:AxiosResponse)= > {
// 對響應數據做點什么
return response;
}, (error:AxiosError)= > {
// 對響應錯誤做點什么
return Promise.reject(error);
});
移除攔截器
const myInterceptor = axios.interceptors.request.use((response: AxiosResponse)= > {/*...*/});
axios.interceptors.request.eject(myInterceptor);
可以給自定義的 axios 實例添加攔截器
const instance = axios.create();
instance.interceptors.request.use((config:InternalAxiosRequestConfig)= > {/*...*/});
指定返回數據的類型
responseType
指定返回數據的類型,默認無此字段。如果設置了此參數,系統將優先返回指定的類型。 選項包括: string:字符串類型; object:對象類型; array_buffer:二進制數組類型。 設置responseType后,response.data中的數據將為指定類型
axios< string, AxiosResponse< string >, null >({
url: 'https://www.xxx.com/info',
method: 'get',
responseType: 'array_buffer',
}).then((res: AxiosResponse) = > {
// 處理請求成功的邏輯
})
注意:也可以通過重寫transformResponse方法,修改返回數據;
axios< string, AxiosResponse< string >, null >({
url: 'https://www.xxx.com/info',
method: 'get',
responseType: 'array_buffer',
transformResponse:(data)= >{
return data
}
}).then((res: AxiosResponse) = > {
// 處理請求成功的邏輯
})
自定義ca證書
axios< infoModel, AxiosResponse< infoModel >, null >({
url: 'https://www.xxx.com/xx',
method: 'get',
caPath: '', //ca證書路徑
}).then((res: AxiosResponse) = > {
//
}).catch((err: AxiosError) = > {
//
})
自定義客戶端證書
axios< infoModel, AxiosResponse< infoModel >, null >({
url: 'https://www.xxx.com/xx',
method: 'get',
caPath: '', //ca證書路徑
clientCert: {
certPath: '', //客戶端證書路徑
certType: 'p12', // 客戶端證書類型,包括pem、der、p12三種
keyPath: '', //客戶端私鑰路徑
keyPasswd: '' // 密碼
}
}).then((res: AxiosResponse) = > {
//
}).catch((err: AxiosError) = > {
//
})
設置代理
axios< string, AxiosResponse< string >, null >({
url: 'xxx',
method: 'get',
proxy:{
host: 'xxx',
port: xx,
exclusionList: []
}
}).then((res: AxiosResponse) = > {
//
}).catch((err: AxiosError) = > {
//
})
證書鎖定
證書鎖定的用法如下:
需要在配置文件中對證書進行相關信息的配置:配置文件路徑為:entry/src/main/resources/base/profile/network_config.json
配置文件:network_config
{
"network-security-config": {
"domain-config": [
{
"domains": [
{
"include-subdomains": true,
"name": "x.x.x.x" // ip地址或域名
}
],
"pin-set": {
"expiration": "2024-8-6", //證書鎖定的有效期
"pin": [
{
"digest-algorithm": "sha256", //消息摘要的哈希算法,支持格式是sha256
"digest": "WAFcHG6pAINrztx343ccddfzLOdfoDS9pPgMv2XHk=" //消息摘要
}
]
}
}
]
}
}
digest字段消息摘要獲取
使用openssl從服務器獲取證書,并提取出消息摘要
openssl s_client -connect host:port 2 >&1 < /dev/null
| sed -n '/-----BEGIN/,/-----END/p'
| openssl x509 -noout -pubkey
| openssl pkey -pubin -outform der
| openssl dgst -sha256 -binary
| openssl enc -base64
上傳下載文件
上傳文件示例
- 上傳文件需要單獨導入FormData模塊
- 當前版本只支持 Stage 模型
- 上傳類型支持uri和ArrayBuffer,uri支持“internal”協議類型,僅支持"internal"協議類型,"internal://cache/"為必填字段,示例: internal://cache/path/to/file.txt
- 請求的表單數據值為string類型
當上傳的內容為ArrayBuffer時,用法如下
import axios from '@ohos/axios'
import { FormData } from '@ohos/axios'
import fs from '@ohos.file.fs';
// ArrayBuffer
let formData = new FormData()
let cacheDir = getContext(this).cacheDir
try {
// 寫入
let path = cacheDir + '/hello.txt';
let file = fs.openSync(path, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
fs.writeSync(file.fd, "hello, world"); // 以同步方法將數據寫入文件
fs.fsyncSync(file.fd); // 以同步方法同步文件數據。
fs.closeSync(file.fd);
// 讀取
let file2 = fs.openSync(path, 0o2);
let stat = fs.lstatSync(path);
let buf2 = new ArrayBuffer(stat.size);
fs.readSync(file2.fd, buf2); // 以同步方法從流文件讀取數據。
fs.fsyncSync(file2.fd);
fs.closeSync(file2.fd);
formData.append('file', buf2);
} catch (err) {
console.info('err:' + JSON.stringify(err));
}
// 發送請求
axios.post< string, AxiosResponse< string >, FormData >(this.uploadUrl, formData, {
headers: { 'Content-Type': 'multipart/form-data' },
context: getContext(this),
onUploadProgress: (progressEvent: AxiosProgressEvent): void = > {
console.info(progressEvent && progressEvent.loaded && progressEvent.total ? Math.ceil(progressEvent.loaded / progressEvent.total * 100) + '%' : '0%');
},
}).then((res: AxiosResponse) = > {
console.info("result" + JSON.stringify(res.data));
}).catch((error: AxiosError) = > {
console.error("error:" + JSON.stringify(error));
})
當上傳的uri時,用法如下
import axios from '@ohos/axios'
import { FormData } from '@ohos/axios'
let formData = new FormData()
formData.append('file', 'internal://cache/blue.jpg')
// 發送請求
axios.post< string, AxiosResponse< string >, FormData >('https://www.xxx.com/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
context: getContext(this),
onUploadProgress: (progressEvent: AxiosProgressEvent): void = > {
console.info(progressEvent && progressEvent.loaded && progressEvent.total ? Math.ceil(progressEvent.loaded / progressEvent.total * 100) + '%' : '0%');
},
}).then((res: AxiosResponse< string >) = > {
console.info("result" + JSON.stringify(res.data));
}).catch((err: AxiosError) = > {
console.error("error:" + JSON.stringify(err));
})
下載文件示例
設置下載路徑filePath(默認在'internal://cache/'路徑下)。
關于filePath
filePath:'workspace/test.txt':默認路徑下創建workspace路徑,并將文件存儲在workspace路徑下。
filePath:'test.txt':將文件存儲在默認路徑下。
filePath:'workspace/':默認路徑下創建workspace路徑,并將文件存儲在workspace路徑下。
- 當前版本只支持 Stage 模型 下載文件時,如果filePath已存在該文件則下載失敗,下載之前需要先刪除文件。
let filePath = getContext(this).cacheDir + '/blue.jpg'
// 下載。如果文件已存在,則先刪除文件。
try {
fs.accessSync(filePath);
fs.unlinkSync(filePath);
} catch(err) {}
axios({
url: 'https://www.xxx.com/blue.jpg',
method: 'get',
context: getContext(this),
filePath: filePath ,
onDownloadProgress: (progressEvent: AxiosProgressEvent): void = > {
console.info("progress: " + progressEvent && progressEvent.loaded && progressEvent.total ? Math.ceil(progressEvent.loaded / progressEvent.total * 100) : 0)
}
}).then((res)= >{
console.info("result: " + JSON.stringify(res.data));
}).catch((error)= >{
console.error("error:" + JSON.stringify(error));
})
錯誤處理
錯誤處理示例代碼
axios.get< string, AxiosResponse< string >, null >('/user/12345')
.catch((error:AxiosError)= > {
console.log(JSON.stringify(error.message));
console.log(JSON.stringify(error.code));
console.log(JSON.stringify(error.config));
});
錯誤碼
- 網絡請求異常時,catch方法接收到異常,異常錯誤碼 [請點擊查看]
- 錯誤常量
名稱 | 參數類型 | 可讀 | 可寫 | 說明 |
---|---|---|---|---|
NETWORK_MOBILE | number | 是 | 否 | 使用蜂窩網絡時允許下載的位標志。 |
NETWORK_WIFI | number | 是 | 否 | 使用WLAN時允許下載的位標志。 |
ERROR_CANNOT_RESUME7+ | number | 是 | 否 | 某些臨時錯誤導致的恢復下載失敗。 |
ERROR_DEVICE_NOT_FOUND7+ | number | 是 | 否 | 找不到SD卡等存儲設備。 |
ERROR_FILE_ALREADY_EXISTS7+ | number | 是 | 否 | 要下載的文件已存在,下載會話不能覆蓋現有文件。 |
ERROR_FILE_ERROR7+ | number | 是 | 否 | 文件操作失敗。 |
ERROR_HTTP_DATA_ERROR7+ | number | 是 | 否 | HTTP傳輸失敗。 |
ERROR_INSUFFICIENT_SPACE7+ | number | 是 | 否 | 存儲空間不足。 |
ERROR_TOO_MANY_REDIRECTS7+ | number | 是 | 否 | 網絡重定向過多導致的錯誤。 |
ERROR_UNHANDLED_HTTP_CODE7+ | number | 是 | 否 | 無法識別的HTTP代碼。 |
ERROR_UNKNOWN7+ | number | 是 | 否 | 未知錯誤。 |
PAUSED_QUEUED_FOR_WIFI7+ | number | 是 | 否 | 下載被暫停并等待WLAN連接,因為文件大小超過了使用蜂窩網絡的會話允許的最大值。 |
PAUSED_UNKNOWN7+ | number | 是 | 否 | 未知原因導致暫停下載。 |
PAUSED_WAITING_FOR_NETWORK7+ | number | 是 | 否 | 由于網絡問題(例如網絡斷開)而暫停下載。 |
PAUSED_WAITING_TO_RETRY7+ | number | 是 | 否 | 發生網絡錯誤,將重試下載會話。 |
SESSION_FAILED7+ | number | 是 | 否 | 下載會話已失敗,將不會重試。 |
SESSION_PAUSED7+ | number | 是 | 否 | 下載會話已暫停。 |
SESSION_PENDING7+ | number | 是 | 否 | 正在調度下載會話。 |
SESSION_RUNNING7+ | number | 是 | 否 | 下載會話正在進行中。 |
SESSION_SUCCESSFUL7+ | number | 是 | 否 | 下載會話已完成。 |
鴻蒙開發知識更新在[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
]前往參考。
約束與限制
在下述版本驗證通過: DevEco Studio: 4.1 Canary2(4.1.3.325), SDK: API11(4.1.0.36)
注意:除雙向證書驗證及證書鎖定功能必須使用API11外,其余功能支持API9、API10
FAQ
- 服務器返回多個cookie,response.header中只能讀取首個cookie。
由于該庫底層依賴ohos.net.http模塊,ohos.net.http也存在此問題,204.1.0.33 鏡像版本已修復此問題。
審核編輯 黃宇
-
服務器
+關注
關注
12文章
9231瀏覽量
85626 -
鴻蒙
+關注
關注
57文章
2369瀏覽量
42900
發布評論請先 登錄
相關推薦
評論