前端带token下载文件

前端带token下载文件(我用的是React,但都大同小异)

不多说直接上代码

// 获取域名地址
export const getServiceHost = () => {
  const { host } = window.location;
    // 看当前域名是否是生产环境
    // 是生产环境 则匹配后端的 生产环境
    // 不是生产环境 则匹配后端的 测试环境
  return host === 'zhao.com' ? '//zhao.pro.com' : '//zhao.sit.com';
    // 本地调试
  // return host === 'zhao.com' ? '//zhao.pro.com' : '//localhost:9090';
}


// 下载文件
export const download = (link: string, params: any) => {
    // token 获取
  let token = window?.localStorage?.getItem("zhao-com-token")
  if (token === undefined || token === null) {
    token = ""
  }
  const xhr = new XMLHttpRequest()
  // POST请求,link,async(是否异步)
  xhr.open("POST", `${getServiceHost()}/zhao/${link}`, true)
  // 设置请求头参数的方式,如果没有可忽略此行代码
  xhr.setRequestHeader("token", token)
  xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8")
  // 设置响应类型为 blob
  xhr.responseType = "blob"
  // 关键部分
  xhr.onload = function () {
    // 如果请求执行成功
    if (this.status === 200) {
        // 获取二进制流
      const blob = this.response
      // 创建一个a标签
      const a = document.createElement("a")
      // blob.type = "application/octet-stream"
      // 创键临时link对象
      const url = window.URL.createObjectURL(new Blob([blob]))
      a.href = url
      // 获取指定响应头, 从响应头中获取文件名
      const temp = xhr.getResponseHeader('Content-Disposition');
      let fileName: any = temp?.split(";")?.[1]?.split("filename=")?.[1];
        // 解决乱码问题
      fileName = decodeURIComponent(fileName);
      // 设置下载文件的名字
      a.download = fileName
        // 点击 a标签
      a.click()
      // 释放之前创建的URL对象
      window.URL.revokeObjectURL(link)
    }
  }
  // 发送请求
  xhr.send(JSON.stringify(params))
}

下载文件示例

<Button
            style={{ backgroundColor: '#0a64e7', borderColor: '#0a64e7' }}
            key="button"
            type="primary"
            onClick={async () => {
        // 参数
              const params = {
                "beginDate": beginDate,
                "endDate": endDate
              }
              // 方法
              download('/service/card/export', params)
            }}
          >
            导出
          </Button>

request封装方法

/* eslint-disable */

/** Request 网络请求工具 更详细的 api 文档: https://github.com/umijs/umi-request */
import { extend } from 'umi-request';
import type { RequestOptionsInit } from 'umi-request';
import { notification } from 'antd';
import { history } from 'umi';
import { stringify } from 'querystring';
import { getServiceHost } from './utils';

const codeMessage: Record<number, string> = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队(异步任务)。',
  204: '删除数据成功。',
  400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限(令牌、用户名、密码错误)。',
  403: '用户得到授权,但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除,且不会再得到的。',
  422: '当创建一个对象时,发生一个验证错误。',
  500: '服务器发生错误,请检查服务器。',
  502: '网关错误。',
  503: '服务不可用,服务器暂时过载或维护。',
  504: '网关超时。',
};

/** 异常处理程序 */
const errorHandler = (error: { response: Response }): Response => {
  const { response } = error;
  if (response && response.status) {
    const errorText = codeMessage[response.status] || response.statusText;
    const { status, url } = response;

    notification.error({
      message: `请求错误 ${status}: ${url}`,
      description: errorText,
    });
  } else if (!response) {
    notification.error({
      description: '您的网络发生异常,无法连接服务器',
      message: '网络异常',
    });
  }
  return response;
};

/** 配置request请求时的默认参数 */
const request = extend({
  prefix: '/zhao/service/',
  errorHandler, // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
});

request.interceptors.request.use((url: string, options: RequestOptionsInit) => {
  const authHeader = {
      // 请求头 添加token
    memberToken: localStorage.getItem('zhao-com-token') || '',
    // 'Content-Type': 'application/json;charset=utf-8',
  };
  const baseDomain = getServiceHost();
  return {
    url: baseDomain + url,
    options: { ...options, interceptors: true, headers: authHeader },
  };
});

request.interceptors.response.use(async (response: Response): Promise<Response> => {
  const data = await response.clone().json();
	// 处理异常
  if (response.status === 200 && data.resCode !== '20000') {
    notification.error({
      message: data.msg,
    });
      // token失效
    if (data.resCode === '20003') {
        // 删除token
      if (localStorage.getItem('zhao-com-token')) {
        localStorage.removeItem('zhao-com-token');
      }
      // 不包含 登录的url 就跳转到登录页面 修复多次请求token失效后要登录多次进行跳转的bug
      if (window.location.pathname.indexOf("/user/login") === -1) {
        history.push({
          pathname: '/user/login',
          search: stringify({
            redirect: window.location.href,
          }),
        });
      }
    }
  }
  return response;
});

export default request;

// 20000=成功
// 20002=登录失败
// 20005=该用户无此菜单权限
// 20003=token失效
// 90000=系统异常
// 90001=数据库异常
// 90004=参数异常
// 90006=操作异常

请求示例

import request from '@/utils/request';

export async function passwordReset(params: any) {
  return request('passwordReset', {
    method: 'POST',
    data: params,
  });
}

后端示例

    /**
     * 报表列表导出
     */
    @PostMapping("exportList")
    @ApiOperation("报表--列表导出(完成)")
    public ResponseEntity<ByteArrayResource> exportList(@RequestBody @Validated CardSalesReportListDto dto) throws UnsupportedEncodingException {
        ByteArrayResource byteArrayResource = cardSalesReportService.exportList(dto);

        String fileName = "报表.xlsx";
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Access-Control-Expose-Headers","Content-Disposition");
        headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ";" + "filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8"));
        headers.add("Pragma", "no-cache");
        headers.add("Last-Modified", new Date().toString());
        headers.add("ETag", String.valueOf(System.currentTimeMillis()));
        headers.add("Content-Type", "application/vnd.ms-excel;charset=UTF-8");
        headers.add("Content-Encoding", "UTF-8");
        return ResponseEntity.ok().headers(headers)
                .contentLength(byteArrayResource.contentLength())
                .body(byteArrayResource);
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我认不到你

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值