Skip to content

Commit e225159

Browse files
authoredJan 21, 2025
fix: request download and upload not support responseReturn (vbenjs#5456)
* fix: request download and upload not support `responseReturn` * docs: update * fix: type of request client upload result
1 parent 195ceec commit e225159

File tree

7 files changed

+93
-28
lines changed

7 files changed

+93
-28
lines changed
 

‎packages/effects/request/src/request-client/modules/downloader.test.ts

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ describe('fileDownloader', () => {
3131
expect(result).toEqual(mockBlob);
3232
expect(mockAxiosInstance.get).toHaveBeenCalledWith(url, {
3333
responseType: 'blob',
34+
responseReturn: 'body',
3435
});
3536
});
3637

@@ -51,6 +52,7 @@ describe('fileDownloader', () => {
5152
expect(mockAxiosInstance.get).toHaveBeenCalledWith(url, {
5253
...customConfig,
5354
responseType: 'blob',
55+
responseReturn: 'body',
5456
});
5557
});
5658

‎packages/effects/request/src/request-client/modules/downloader.ts

+22-12
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,38 @@
1-
import type { AxiosRequestConfig } from 'axios';
2-
31
import type { RequestClient } from '../request-client';
4-
import type { RequestResponse } from '../types';
2+
import type { RequestClientConfig } from '../types';
3+
4+
type DownloadRequestConfig = {
5+
/**
6+
* 定义期望获得的数据类型。
7+
* raw: 原始的AxiosResponse,包括headers、status等。
8+
* body: 只返回响应数据的BODY部分(Blob)
9+
*/
10+
responseReturn?: 'body' | 'raw';
11+
} & Omit<RequestClientConfig, 'responseReturn'>;
512

613
class FileDownloader {
714
private client: RequestClient;
815

916
constructor(client: RequestClient) {
1017
this.client = client;
1118
}
12-
13-
public async download(
19+
/**
20+
* 下载文件
21+
* @param url 文件的完整链接
22+
* @param config 配置信息,可选。
23+
* @returns 如果config.responseReturn为'body',则返回Blob(默认),否则返回RequestResponse<Blob>
24+
*/
25+
public async download<T = Blob>(
1426
url: string,
15-
config?: AxiosRequestConfig,
16-
): Promise<RequestResponse<Blob>> {
17-
const finalConfig: AxiosRequestConfig = {
27+
config?: DownloadRequestConfig,
28+
): Promise<T> {
29+
const finalConfig: DownloadRequestConfig = {
30+
responseReturn: 'body',
1831
...config,
1932
responseType: 'blob',
2033
};
2134

22-
const response = await this.client.get<RequestResponse<Blob>>(
23-
url,
24-
finalConfig,
25-
);
35+
const response = await this.client.get<T>(url, finalConfig);
2636

2737
return response;
2838
}

‎packages/effects/request/src/request-client/modules/uploader.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import type { AxiosRequestConfig, AxiosResponse } from 'axios';
2-
31
import type { RequestClient } from '../request-client';
2+
import type { RequestClientConfig } from '../types';
43

54
class FileUploader {
65
private client: RequestClient;
@@ -9,18 +8,18 @@ class FileUploader {
98
this.client = client;
109
}
1110

12-
public async upload(
11+
public async upload<T = any>(
1312
url: string,
1413
data: Record<string, any> & { file: Blob | File },
15-
config?: AxiosRequestConfig,
16-
): Promise<AxiosResponse> {
14+
config?: RequestClientConfig,
15+
): Promise<T> {
1716
const formData = new FormData();
1817

1918
Object.entries(data).forEach(([key, value]) => {
2019
formData.append(key, value);
2120
});
2221

23-
const finalConfig: AxiosRequestConfig = {
22+
const finalConfig: RequestClientConfig = {
2423
...config,
2524
headers: {
2625
'Content-Type': 'multipart/form-data',

‎packages/effects/request/src/request-client/preset-interceptors.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ export const defaultResponseInterceptor = ({
2525
if (config.responseReturn === 'raw') {
2626
return response;
2727
}
28-
const code = responseData[codeField];
29-
if (
30-
status >= 200 && status < 400 && isFunction(successCode)
31-
? successCode(code)
32-
: code === successCode
33-
) {
28+
29+
if (status >= 200 && status < 400) {
3430
if (config.responseReturn === 'body') {
3531
return responseData;
36-
} else {
32+
} else if (
33+
isFunction(successCode)
34+
? successCode(responseData[codeField])
35+
: responseData[codeField] === successCode
36+
) {
3737
return isFunction(dataField)
3838
? dataField(responseData)
3939
: responseData[dataField];

‎packages/effects/request/src/request-client/types.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import type {
77

88
type ExtendOptions = {
99
/** 响应数据的返回方式。
10-
* raw: 原始的AxiosResponse,包括headers、status等。
11-
* body: 返回响应数据的BODY部分。
12-
* data: 解构响应的BODY数据,只返回其中的data节点数据。
10+
* raw: 原始的AxiosResponse,包括headers、status等,不做是否成功请求的检查
11+
* body: 返回响应数据的BODY部分(只会根据status检查请求是否成功,忽略对code的判断,这种情况下应由调用方检查请求是否成功)
12+
* data: 解构响应的BODY数据,只返回其中的data节点数据(会检查status和code是否为成功状态)
1313
*/
1414
responseReturn?: 'body' | 'data' | 'raw';
1515
};
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import type { RequestResponse } from '@vben/request';
2+
3+
import { requestClient } from '../request';
4+
5+
/**
6+
* 下载文件,获取Blob
7+
* @returns Blob
8+
*/
9+
async function downloadFile1() {
10+
return requestClient.download<Blob>(
11+
'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
12+
);
13+
}
14+
15+
/**
16+
* 下载文件,获取完整的Response
17+
* @returns RequestResponse<Blob>
18+
*/
19+
async function downloadFile2() {
20+
return requestClient.download<RequestResponse<Blob>>(
21+
'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
22+
{
23+
responseReturn: 'raw',
24+
},
25+
);
26+
}
27+
28+
export { downloadFile1, downloadFile2 };

‎playground/src/views/demos/features/file-download/index.vue

+26
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
<script setup lang="ts">
2+
import { ref } from 'vue';
3+
24
import { Page } from '@vben/common-ui';
35
import {
46
downloadFileFromBase64,
@@ -9,7 +11,23 @@ import {
911
1012
import { Button, Card } from 'ant-design-vue';
1113
14+
import { downloadFile1, downloadFile2 } from '#/api/examples/download';
15+
1216
import imageBase64 from './base64';
17+
18+
const downloadResult = ref('');
19+
20+
function getBlob() {
21+
downloadFile1().then((res) => {
22+
downloadResult.value = `获取Blob成功,长度:${res.size}`;
23+
});
24+
}
25+
26+
function getResponse() {
27+
downloadFile2().then((res) => {
28+
downloadResult.value = `获取Response成功,headers:${JSON.stringify(res.headers)},长度:${res.data.size}`;
29+
});
30+
}
1331
</script>
1432

1533
<template>
@@ -70,5 +88,13 @@ import imageBase64 from './base64';
7088
Download TxT
7189
</Button>
7290
</Card>
91+
92+
<Card class="my-5" title="Request download">
93+
<Button type="primary" @click="getBlob"> 获取Blob </Button>
94+
<Button type="primary" class="ml-4" @click="getResponse">
95+
获取Response
96+
</Button>
97+
<div class="mt-4">{{ downloadResult }}</div>
98+
</Card>
7399
</Page>
74100
</template>

0 commit comments

Comments
 (0)
Please sign in to comment.