前言:2022年下半年本人开发了一款基于 Tauri 的应用程序,从 Tauri 小白到项目上线一路收获颇丰。现将开发过程中踩过的坑做一下总结,本系列不定期更新,示例源码地址:tauri-study-examples。
接口请求处理
项目中没有使用 axios 等前端 HTTP 请求库,使用的是 Tauri 内置的 fetch 方法,但该方法使用比较简单,没有请求拦截器或响应拦截器相关配置,所以我们有必要在此基础上做下二次封装。
1. 配置安全域名
在 tauri.conf.json 里添加配置
"allowlist": {
"http": {
"scope": [
"https://xxx/*"
]
}
}
2. 封装 http 请求
新建 utils/http.ts 文件
import { fetch, ResponseType } from '@tauri-apps/api/http';
import qs from 'qs';
const isAbsoluteURL = (url: string): boolean => {
return /^([a-z][a-z\d+-.]*:)?///i.test(url);
};
const combineURLs = (baseURL: string, relativeURL: string): string => {
return relativeURL
? baseURL.replace(//+$/, '') + '/' + relativeURL.replace(/^/+/, '')
: baseURL;
};
const buildFullPath = (baseURL: string, requestedURL: string) => {
if (baseURL && !isAbsoluteURL(requestedURL)) {
return combineURLs(baseURL, requestedURL);
}
return requestedURL;
};
const buildURL = (url: string, params: any): string => {
if (!params) {
return url;
}
const serializedParams = qs.stringify(params);
if (serializedParams) {
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
}
return url;
};
const server = '';
const baseURL = `${server}/api/v1`;
const BODY_TYPE = {
Form: 'Form',
Json: 'Json',
Text: 'Text',
Bytes: 'Bytes',
};
const commonOptions = {
timeout: 60,
responseType: ResponseType.JSON,
};
const http = (url: string, options: any = {}) => {
const params = { ...options.params };
if (!options.headers) options.headers = {};
// todo 可以往 headers 中添加 token 或 cookie 等信息
if (options?.body) {
if (options.body.type === BODY_TYPE.Form) {
options.headers['Content-Type'] = 'multipart/form-data';
}
}
options = { ...commonOptions, ...options };
return fetch(buildURL(buildFullPath(baseURL, url), params), options)
.then(({ status, data }) => {
if (status >= 200 && status < 400) {
return { data };
}
return Promise.reject({ status, data });
})
.catch((err) => {
console.error(err);
return Promise.reject(err);
});
};
export default http;
3. 简单使用
GET 请求
import http from '@/utils/http';
const params = {};
http('https://www.baidu.com/get', {
method: 'get',
params,
});
POST 请求
import { Body } from '@tauri-apps/api/http';
import http from '@/utils/http';
const body = Body.json({
test: '1',
});
http('https://www.baidu.com/post', {
method: 'post',
body,
});
POST 上传文件
import { Body } from '@tauri-apps/api/http';
import http from '@/utils/http';
const generateFileInfo = (
arrayBuffer: any,
mime: string,
fileName: string,
) => {
return {
file: new Uint8Array(arrayBuffer),
mime,
fileName,
};
};
const arrayBuffer = await file.arrayBuffer();
const body = Body.form({
file: generateFileInfo(arrayBuffer, file.type, file.name),
// todo 其他参数
});
http('https://www.baidu.com/upload', {
method: 'post',
body,
});
|