Downloading Files via POST Requests
When dealing with file downloads that require sending request payloads, the POST method is typically used. Here's how to implement a POST-based file download:
API Request Function
export const downloadFile = (payload, projectId) => {
return apiClient({
url: API_BASE + '/documents/export',
headers: {
"Project-Id": projectId,
httpWhite: true,
},
responseType: "blob",
method: 'post',
data: payload
})
}
Triggering the Download
<el-button size="small" type="primary" @click="handleDownload(row)">
<i class="iconfont yun-xiazai"></i>
<span>Export Data</span>
</el-button>
const handleDownload = (row) => {
const requestPayload = {
identifier: 'data_export',
recordId: row.id,
};
downloadFile(requestPayload, this.currentProjectId).then((response) => {
if (response.status === 200) {
this.processDownload(response);
}
});
}
Processing the Blob Response
processDownload(response) {
if (!response.data) {
return;
}
const contentDisposition = response.headers["content-disposition"];
const fileName = decodeURIComponent(
contentDisposition.split("filename=")[1]
);
const blob = new Blob([response.data], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8",
});
const url = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
}
Downloading Files via GET Requests
For simpler download scenarios where parameters can be passed as query strings, the GET method offers two approaches.
Simple GET Download
This approach works in most cases where authentication tokens and basic parameters suffice:
const buildDownloadUrl = () => {
const queryParams = new URLSearchParams({
token: getAuthToken(),
projectId: currentProjectId,
spaceId: workspaceId
});
return `${API_BASE}/reports/download?${queryParams.toString()}`;
};
const initiateDownload = () => {
window.open(buildDownloadUrl(), "_self");
};
GET Download with Custom Headers
When the download endpoint requires specific headers beyond standard query parameters, use the Blob response approach:
export const fetchDownload = (parameters) => apiClient({
url: API_BASE + '/files/export',
headers: {
"Project-Id": parameters.projectId,
},
method: 'get',
responseType: 'blob',
params: parameters,
})
// Execute Export
executeExport() {
let requestParams = { ...this.filterParams };
fetchDownload(requestParams).then((response) => {
if (response.status === 200) {
const contentDisposition = response.headers["content-disposition"];
const fileName = decodeURIComponent(
contentDisposition.split("filename=")[1]
);
const blob = new Blob([response.data]);
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.style.display = "none";
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
}
});
}
Key Implementation Details
Both approaches share common patterns for handling binary file responses:
- responseType: "blob" - Essential for receiving binary data instead of text
- Content-Disposition header - Contains the original filename assigned by the server
- URL.createObjectURL() - Creates a local URL reference to the Blob for download linking
- Cleanup - Always revoke the object URL after download to prevent memory leaks
Choose the appropriate method based on your backend API requirements - simple GET for straightforward downloads, POST or header-based GET for more complex scenarios requiring authentication or payload data.