프런트 엔드에서 파일을 다운로드하는 여러 방법

1. 태그 다운로드 다운로드
백엔드는 다운로드 가능한 url 파일 또는 프런트 엔드에 로컬로 저장된 파일을 반환하고 경로를 통해 다운로드합니다.
(1) 로컬 저장을 위해 프런트 엔드에 리소스를 넣고 패키징 후 서버에서 업로드
여기에 사진 설명 삽입

// 本地资源下载,引入路径即可,这里的路径指的是打包后文件与代码文件的相对路径
<a href="./import-template.xlsx" download target="_blank">
  下载上传模板 
</a>

(2) 서버를 요청하고 반환 된 url을 태그의 href 속성에 넣습니다.
다음은 의사 코드입니다. 구현 단계에서는 먼저 url을 가져 와서 변수로 사용하여 a의 href 속성에 넣습니다. 태그입니다. 다른 프레임 워크 방법은 다릅니다.

let requestUrl = 'xxxxxx';
let responseUrl = '';
fetch(requestUrl ).then(res => {
    
    
 responseUrl = res.data.url
})

// dom节点渲染如果responseUrl出现跨域,download将失效,无法下载
<a href=`${
    
    responseUrl }` download target="_blank">
  下载上传模板 
</a>

(3) 프레임 워크에 의존하지 않고 네이티브 js는 클릭 및 다운로드 방법을 인식합니다.

//点击某个按钮触发事件
 const onClickDownFile = (id) => {
    
    
let requestUrl = `xxxxxx${
    
    id}xxxx`;
fetch(requestUrl).then(res => {
    
    
	//为了解决a标签跨域无法下载的问题
	const x = new XMLHttpRequest();
      x.open('GET', res.data.url, true);
      x.responseType = 'blob';
      x.onload = () => {
    
    
        const dataurl = window.URL.createObjectURL(x.response);
        const a = document.createElement('a');
        a.href = res.data.url;
        a.download = res.data.url;
        a.click();
        a.remove();
      };
      x.send();
})
  };

2. 백엔드 인터페이스는 바이너리 스트림을 반환하고 프런트 엔드는 수신 및 처리해야합니다.

import {
    
     stringify } from 'qs';

type Method = 'GET' | 'POST';

/**
 * 下载文件
 * @param url 接口路径
 * @param data 请求的参数
 * @param method 请求方式
 * @param type 下载文件的类型
 * @param fileName 自定义文件名称
 */
export const download = (
  url: string,
  data: any,
  method: Method,
  type: string,
  fileName?: string,
) => {
    
    
  /** fetch 配置项 */
  const params: RequestInit = {
    
    
    method,
    headers: {
    
    
      Authorization: '',
      'response-type': 'arraybuffer',
    },
  };

  if (method === 'GET') {
    
    
    // 每次请求添加时间戳,避免 GET 请求遭遇 HTTP 缓存
    data._ = new Date().getTime();

    // 请求参数合并到 URL 上
    url += `?${
    
    stringify(data)}`;
  } else {
    
    
    params.body = JSON.stringify(data);
  }

  return fetch(url, params)
    .then((response) => {
    
    
      if (response.status === 200 && response.body) {
    
    
        if (!fileName) {
    
    
          const cd = response.headers.get('content-disposition');
          const cds = cd?.split('filename=') || [];
          if (cds[1]) {
    
    
            fileName = decodeURIComponent(cds[1]);
          }
        }
        return response.blob();
      }

      return Promise.reject();
    })
    .then((_blob) => {
    
    
      const blob = new Blob([_blob], {
    
    
        type,
      });
      const link = document.createElement('a');
      link.href = window.URL.createObjectURL(blob);
      link.download = fileName || 'file';
      link.click();

      return 'done';
    });
};

사용하는 방법

download(
    ’xxxx‘,
    {
    
    },
    "GET", //或者"POST"
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',
    fileName, //文件名称
  )

type은 파일 유형이고 다른 파일 유형에는 다른 유형이 있습니다.

접미사 MIME 유형
.문서 응용 프로그램 / msword
.docx application / vnd.openxmlformats-officedocument.wordprocessingml.document
.xls 애플리케이션 /vnd.ms-excel
.xlsx application / vnd.openxmlformats-officedocument.spreadsheetml.sheet
.ppt application / vnd.ms-powerpoint
.pptx application / vnd.openxmlformats-officedocument.presentationml.presentation

3. 백엔드는 적절하게 바이너리 스트림 파일을 반환합니다.
프로젝트에서 이러한 요구 사항이 발생했습니다. 프런트 엔드는 파일을 가져오고 백 엔드는 구문 분석하여 결과를 반환합니다. 성공하면 반환 된 데이터는 null이고 코드는 0입니다. 실패하면 Excel을 반환합니다. 이진 스트림 파일을 엑셀 파일에 저장합니다. 실패 이유가 표시되고 파일이 자동으로 다운로드됩니다.


const downloadBlob = (blob: Blob, type: string, fileName?: string) => {
    
    
  const newBlob = new Blob([blob], {
    
    
    type,
  });
  const link = document.createElement('a');
  link.href = window.URL.createObjectURL(newBlob);
  link.download = fileName || '错误文件';
  link.click();
};

export const FileUpload = (url: string, file: FormData): Promise => {
    
    
  /** fetch 配置项 */
  const params: RequestInit = {
    
    
    method: 'POST',
    headers: {
    
    
      Authorization: '',
    },
    body: file,
  };

  return fetch(url, params).then((response) => {
    
    
    if (response.status === 200 && response.body) {
    
    
      return new Promise((resolve, reject) => {
    
    
        const contentType = response.headers.get('content-type') || '';

        if (contentType.indexOf('application/json') >= 0) {
    
    
          // 返回的是 JSON 文件
          response.json().then(resolve);
        } else if (contentType.indexOf('application/vnd.ms-excel') >= 0) {
    
    
          // 返回的是 excel 文件
          response.blob().then((_blob) => {
    
    
            const cd = response.headers.get('content-disposition');
            const cds = cd?.split('filename=') || [];

            downloadBlob(
              _blob,
              'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',
              decodeURIComponent(cds[1]),
            );

            resolve();
          });
        } else {
    
    
          // 暂时不知道是啥
          reject();
        }
      });
    }

    return Promise.reject();
  });
};


콘텐츠 유형에는 여러 유형이 있으며 각 유형 은 서로 다른 반환 유형에 해당합니다. 콘텐츠 유형 비교 의 전체 목록 : https://tool.oschina.net/commons/

추천

출처blog.csdn.net/glorydx/article/details/110226086