Condivisione della tecnologia

Come scaricare file front-end

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Metodo 1: download diretto con un tag

<a href="链接" >下载</a>
  • 1

Un collegamento a un file (solitamente un file sul server). Questo collegamento viene generalmente inserito nella barra degli indirizzi per visualizzare l'anteprima, non per scaricare un allegato.

Se desideri cambiarlo in un download di allegato, puoi scegliere uno dei due metodi seguenti:
1. Elaborazione backend, aggiungi un'intestazione di risposta al backend

res.setHeader('Content-Dispostion', 'attachment', 'name.pdf')

  • 1
  • 2

2. Aggiungi l'attributo download al tag a

<a href="链接" download="文件名" >下载</a>
  • 1

Svantaggi del metodo uno:

Svantaggi: quando si utilizza il tag a per scaricare un file in JavaScript, il download del browser viene attivato direttamente tramite l'evento clic del tag a. L'intestazione della richiesta non può essere impostata perché si tratta di una semplice richiesta GET. Se il download di questo file richiede il trasporto di un token, il tag a non sarà efficace (il tag a non può contenere il token) e diventerà un'anteprima.
Soluzione: il tag a può contenere cookie, quindi esiste un'altra soluzione. Prima di scaricare il file, inviare una richiesta per ottenere un token temporaneo e trasferirlo tramite il cookie. Il download del tag a è un download in streaming, che renderà i file del server come l'acqua corrente Memorizzato sul disco locale, quindi il download può essere visto direttamente e il file non verrà memorizzato nella cache del browser.

Metodo del titolo due: utilizzare XMLHttpRequest o la richiesta API Fetch.

Scrivi un metodo per scaricare (sostanzialmente usa ancora il tag a per scaricare)
Questo metodo può essere una richiesta Ajax, che può trasportare un token e quindi convertire il file del server richiesto in un BLOB, creare un tag per il download, creare un elemento di collegamento virtuale e simulare un clic per il download. Questo metodo occuperà il thread front-end.


import fetch from 'isomorphic-fetch';
const exportFile = (url, options) => {
  const projectId = sessionStorage.getItem(PROJECT_ID);
  const downLoadURL = projectId ? BATCH_ACTION_URL_PREFIX.V2 : BATCH_ACTION_URL_PREFIX.V1;
  const defaultOptions = {
    credentials: 'same-origin',
  };
  const newOptions = { ...defaultOptions, ...options };
  if (
    newOptions.method === 'POST' ||
    newOptions.method === 'PUT' ||
    newOptions.method === 'DELETE'
  ) {
    const projectId = sessionStorage.getItem(PROJECT_ID);
    const appId = sessionStorage.getItem(APP_ID);
    const shopId = sessionStorage.getItem(SHOP_ID);
    const params = {};
    projectId && Object.assign(params, { projectId });
    appId && Object.assign(params, { appId });
    shopId && Object.assign(params, { shopId });
    newOptions.body = { ...newOptions.body, ...params };
    if (!(newOptions.body instanceof FormData)) {
      newOptions.headers = {
        Accept: 'application/json',
        'Content-Type': 'application/json; charset=utf-8',
        ...newOptions.headers,
      };
    } else {
      // newOptions.body is FormData
      newOptions.headers = {
        Accept: 'application/json',
        ...newOptions.headers,
      };
    }
  }
  const token = window.localStorage.getItem(TOKEN);
  if (token) {
    newOptions.headers = {
      'X-Authorization': `Bearer ${token}`,
      ...newOptions.headers,
    };
  }
  const lang = localStorage.getItem(LOCALE_KEY);
  if (lang) {
    newOptions.headers = {
      'Accept-Language': lang,
      ...newOptions.headers,
    };
  }
  const requestURL = `${downLoadURL}/${url}`;
  return request(requestURL, newOptions).then(res => {
    let filename;
    if (res.headers) {
      filename = (
        res.headers.get('Content-Disposition') || res.headers.get('content-disposition')
      ).split('attachment;filename=')[1];
    }
    if (res.blob) {
      res.blob().then(blob => {
        var alink = document.createElement('a');
        alink.style.display = 'none';
        alink.target = '_blank';
        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
          // 兼容IE/Edge
          window.navigator.msSaveOrOpenBlob(blob, filename);
        } else {
          alink.href = window.URL.createObjectURL(blob);
          alink.download = filename;
        }
        document.body.appendChild(alink);
        alink.click();
        URL.revokeObjectURL(alink.href); // 释放URL 对象
        document.body.removeChild(alink);
      });
      return res;
    } else {
      if (res.code === 0) {
        return res;
      } else {
        message.warning(res.message);
      }
    }
  });
};

export default exportFile;


export default function request(url: string, options: Object) {
  const defaultOptions = {
    credentials: 'same-origin',
  };
  const newOptions = { ...defaultOptions, ...options };
  if (
    newOptions.method === 'POST' ||
    newOptions.method === 'PUT' ||
    newOptions.method === 'DELETE' ||
    newOptions.method === 'PATCH'
  ) {
    if (!(newOptions.body instanceof FormData)) {
      newOptions.headers = {
        Accept: 'application/json',
        'Content-Type': 'application/json; charset=utf-8',
        ...newOptions.headers,
      };
      newOptions.body = JSON.stringify(newOptions.body);
    } else {
      // newOptions.body is FormData
      newOptions.headers = {
        Accept: 'application/json',
        ...newOptions.headers,
      };
    }
  }

  return fetch(url, newOptions).then(response => checkStatus(response, url, options));
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120

Svantaggi del metodo due:

**Se il file è piccolo, andrà bene. Se il file è grande, farai clic per scaricare, ma non ci sarà risposta. Il download verrà visualizzato dopo alcuni minuti. Questo tempo di attesa è necessario per convertire il file il lato server in un blob (res.blob () Ci è voluto molto tempo) prima che venisse effettuato il download in streaming del tag a (solo qui il riflesso interattivo del download ha iniziato ad apparire sulla pagina)