Skip to content

Commit

Permalink
fix: request download and upload not support responseReturn (#5456)
Browse files Browse the repository at this point in the history
* fix: request download and upload not support `responseReturn`

* docs: update

* fix: type of request client upload result
  • Loading branch information
mynetfan authored Jan 21, 2025
1 parent 195ceec commit e225159
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe('fileDownloader', () => {
expect(result).toEqual(mockBlob);
expect(mockAxiosInstance.get).toHaveBeenCalledWith(url, {
responseType: 'blob',
responseReturn: 'body',
});
});

Expand All @@ -51,6 +52,7 @@ describe('fileDownloader', () => {
expect(mockAxiosInstance.get).toHaveBeenCalledWith(url, {
...customConfig,
responseType: 'blob',
responseReturn: 'body',
});
});

Expand Down
34 changes: 22 additions & 12 deletions packages/effects/request/src/request-client/modules/downloader.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,38 @@
import type { AxiosRequestConfig } from 'axios';

import type { RequestClient } from '../request-client';
import type { RequestResponse } from '../types';
import type { RequestClientConfig } from '../types';

type DownloadRequestConfig = {
/**
* 定义期望获得的数据类型。
* raw: 原始的AxiosResponse,包括headers、status等。
* body: 只返回响应数据的BODY部分(Blob)
*/
responseReturn?: 'body' | 'raw';
} & Omit<RequestClientConfig, 'responseReturn'>;

class FileDownloader {
private client: RequestClient;

constructor(client: RequestClient) {
this.client = client;
}

public async download(
/**
* 下载文件
* @param url 文件的完整链接
* @param config 配置信息,可选。
* @returns 如果config.responseReturn为'body',则返回Blob(默认),否则返回RequestResponse<Blob>
*/
public async download<T = Blob>(
url: string,
config?: AxiosRequestConfig,
): Promise<RequestResponse<Blob>> {
const finalConfig: AxiosRequestConfig = {
config?: DownloadRequestConfig,
): Promise<T> {
const finalConfig: DownloadRequestConfig = {
responseReturn: 'body',
...config,
responseType: 'blob',
};

const response = await this.client.get<RequestResponse<Blob>>(
url,
finalConfig,
);
const response = await this.client.get<T>(url, finalConfig);

return response;
}
Expand Down
11 changes: 5 additions & 6 deletions packages/effects/request/src/request-client/modules/uploader.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { AxiosRequestConfig, AxiosResponse } from 'axios';

import type { RequestClient } from '../request-client';
import type { RequestClientConfig } from '../types';

class FileUploader {
private client: RequestClient;
Expand All @@ -9,18 +8,18 @@ class FileUploader {
this.client = client;
}

public async upload(
public async upload<T = any>(
url: string,
data: Record<string, any> & { file: Blob | File },
config?: AxiosRequestConfig,
): Promise<AxiosResponse> {
config?: RequestClientConfig,
): Promise<T> {
const formData = new FormData();

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

const finalConfig: AxiosRequestConfig = {
const finalConfig: RequestClientConfig = {
...config,
headers: {
'Content-Type': 'multipart/form-data',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ export const defaultResponseInterceptor = ({
if (config.responseReturn === 'raw') {
return response;
}
const code = responseData[codeField];
if (
status >= 200 && status < 400 && isFunction(successCode)
? successCode(code)
: code === successCode
) {

if (status >= 200 && status < 400) {
if (config.responseReturn === 'body') {
return responseData;
} else {
} else if (
isFunction(successCode)
? successCode(responseData[codeField])
: responseData[codeField] === successCode
) {
return isFunction(dataField)
? dataField(responseData)
: responseData[dataField];
Expand Down
6 changes: 3 additions & 3 deletions packages/effects/request/src/request-client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import type {

type ExtendOptions = {
/** 响应数据的返回方式。
* raw: 原始的AxiosResponse,包括headers、status等。
* body: 返回响应数据的BODY部分。
* data: 解构响应的BODY数据,只返回其中的data节点数据。
* raw: 原始的AxiosResponse,包括headers、status等,不做是否成功请求的检查
* body: 返回响应数据的BODY部分(只会根据status检查请求是否成功,忽略对code的判断,这种情况下应由调用方检查请求是否成功)
* data: 解构响应的BODY数据,只返回其中的data节点数据(会检查status和code是否为成功状态)
*/
responseReturn?: 'body' | 'data' | 'raw';
};
Expand Down
28 changes: 28 additions & 0 deletions playground/src/api/examples/download.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { RequestResponse } from '@vben/request';

import { requestClient } from '../request';

/**
* 下载文件,获取Blob
* @returns Blob
*/
async function downloadFile1() {
return requestClient.download<Blob>(
'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
);
}

/**
* 下载文件,获取完整的Response
* @returns RequestResponse<Blob>
*/
async function downloadFile2() {
return requestClient.download<RequestResponse<Blob>>(
'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
{
responseReturn: 'raw',
},
);
}

export { downloadFile1, downloadFile2 };
26 changes: 26 additions & 0 deletions playground/src/views/demos/features/file-download/index.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script setup lang="ts">
import { ref } from 'vue';
import { Page } from '@vben/common-ui';
import {
downloadFileFromBase64,
Expand All @@ -9,7 +11,23 @@ import {
import { Button, Card } from 'ant-design-vue';
import { downloadFile1, downloadFile2 } from '#/api/examples/download';
import imageBase64 from './base64';
const downloadResult = ref('');
function getBlob() {
downloadFile1().then((res) => {
downloadResult.value = `获取Blob成功,长度:${res.size}`;
});
}
function getResponse() {
downloadFile2().then((res) => {
downloadResult.value = `获取Response成功,headers:${JSON.stringify(res.headers)},长度:${res.data.size}`;
});
}
</script>

<template>
Expand Down Expand Up @@ -70,5 +88,13 @@ import imageBase64 from './base64';
Download TxT
</Button>
</Card>

<Card class="my-5" title="Request download">
<Button type="primary" @click="getBlob"> 获取Blob </Button>
<Button type="primary" class="ml-4" @click="getResponse">
获取Response
</Button>
<div class="mt-4">{{ downloadResult }}</div>
</Card>
</Page>
</template>

0 comments on commit e225159

Please sign in to comment.