You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript中处理后端FileResult响应实现页面文件下载

处理ASP.NET FileResult接口的前端Excel下载方案

方法一:直接链接跳转(适合无额外请求头的GET接口)

你的接口是HttpGet类型,这种场景下最简单的方式就是直接触发浏览器对接口URL的请求,浏览器会自动识别文件类型并触发下载:

  • 直接在页面放置静态链接:
<a href="/YourControllerName/Get" download="Data.xlsx">下载Excel文件</a>
  • 或者用JavaScript动态创建链接并触发点击:
function downloadExcel() {
  const downloadLink = document.createElement('a');
  downloadLink.href = '/YourControllerName/Get'; // 替换为实际接口路由
  downloadLink.download = 'Data.xlsx'; // 文件名可自定义,也可与后端返回值一致
  document.body.appendChild(downloadLink);
  downloadLink.click();
  document.body.removeChild(downloadLink);
}

方法二:异步请求处理(适合需携带请求头的场景)

如果接口需要携带授权信息(如JWT Token)或其他自定义请求头,就需要先通过fetch/XMLHttpRequest获取文件的Blob数据,再触发下载:

使用fetch的示例:

async function downloadExcelWithAuth() {
  try {
    const response = await fetch('/YourControllerName/Get', {
      method: 'GET',
      headers: {
        'Authorization': 'Bearer ' + yourAuthToken // 替换为你的授权Token
        // 可添加其他自定义请求头
      }
    });

    if (!response.ok) throw new Error('请求失败,请稍后重试');

    const fileBlob = await response.blob();
    const blobUrl = window.URL.createObjectURL(fileBlob);
    const downloadLink = document.createElement('a');
    
    // 从响应头解析后端返回的文件名
    const contentDisposition = response.headers.get('Content-Disposition');
    let filename = 'Data.xlsx';
    if (contentDisposition) {
      const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
      if (filenameMatch?.[1]) {
        filename = decodeURIComponent(filenameMatch[1].replace(/['"]/g, ''));
      }
    }

    downloadLink.href = blobUrl;
    downloadLink.download = filename;
    document.body.appendChild(downloadLink);
    downloadLink.click();
    
    // 清理临时资源
    window.URL.revokeObjectURL(blobUrl);
    document.body.removeChild(downloadLink);
  } catch (error) {
    console.error('下载失败:', error);
    // 可在此添加前端错误提示逻辑
  }
}

使用XMLHttpRequest的示例:

function downloadExcelXHR() {
  const xhr = new XMLHttpRequest();
  xhr.open('GET', '/YourControllerName/Get', true);
  xhr.setRequestHeader('Authorization', 'Bearer ' + yourAuthToken); // 自定义请求头
  xhr.responseType = 'blob';

  xhr.onload = function() {
    if (xhr.status === 200) {
      const fileBlob = xhr.response;
      const blobUrl = window.URL.createObjectURL(fileBlob);
      const downloadLink = document.createElement('a');
      
      // 解析响应头获取文件名
      const contentDisposition = xhr.getResponseHeader('Content-Disposition');
      let filename = 'Data.xlsx';
      if (contentDisposition) {
        const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
        if (filenameMatch?.[1]) {
          filename = decodeURIComponent(filenameMatch[1].replace(/['"]/g, ''));
        }
      }

      downloadLink.href = blobUrl;
      downloadLink.download = filename;
      document.body.appendChild(downloadLink);
      downloadLink.click();
      
      window.URL.revokeObjectURL(blobUrl);
      document.body.removeChild(downloadLink);
    } else {
      console.error('请求失败,状态码:', xhr.status);
    }
  };

  xhr.onerror = function() {
    console.error('网络请求出错');
  };

  xhr.send();
}

注意事项

  • 请将代码中的/YourControllerName/Get替换为实际的接口路由地址
  • 无自定义请求头需求时,优先使用方法一,简洁高效
  • 解析Content-Disposition响应头可以保证文件名与后端返回的一致,避免自定义文件名不符的问题

内容的提问来源于stack exchange,提问作者Panos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 11:03:20