Handling Binary File Downloads with HTTP Requests in JavaScript

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.

Posted on Mon, 01 Jun 2026 17:36:28 +0000 by dv90