Обмен технологиями

Как скачать файлы внешнего интерфейса

2024-07-12

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

Способ 1. Прямая загрузка с помощью тега.

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

Ссылка на файл (обычно файл на сервере). Эта ссылка обычно вводится в адресную строку для предварительного просмотра, а не для загрузки вложения.

Если вы хотите изменить его на загрузку вложения, вы можете выбрать один из следующих двух методов:
1. Серверная обработка, добавление заголовка ответа в серверную часть.

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

  • 1
  • 2

2. Добавьте атрибут загрузки в тег a.

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

Недостатки первого способа:

Недостатки: при использовании тега a для загрузки файла в JavaScript загрузка браузера запускается непосредственно через событие щелчка тега, и заголовок запроса не может быть установлен, поскольку это простой запрос GET. Если загрузка этого файла требует наличия токена, тег не будет действовать (тег не может содержать токен) и станет предварительным просмотром.
Решение. Тег a может содержать файлы cookie, поэтому есть другое решение. Прежде чем загружать файл, отправьте запрос на получение временного токена и перенесите его через файл cookie. Загрузка тега представляет собой потоковую загрузку, при которой файлы передаются на сервер. как проточная вода. Хранится на локальном диске, поэтому загрузку можно увидеть напрямую, и файл не будет кэшироваться в браузере.

Второй метод заголовка: используйте запрос XMLHttpRequest или Fetch API.

Напишите метод для загрузки (по сути, для загрузки по-прежнему используйте тег)
Этот метод может представлять собой запрос ajax, который может содержать токен, а затем преобразовать запрошенный файл сервера в большой двоичный объект, создать тег для загрузки, создать элемент виртуальной ссылки и имитировать щелчок для загрузки. Этот метод займет внешний поток.


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

Недостатки второго способа:

**Если файл небольшой, это нормально. Если файл большой, вы нажмете кнопку «Загрузить», но ответа не будет. Загрузка появится через несколько минут. Это время ожидания для преобразования файла. серверную часть в блоб (res.blob() Это заняло очень много времени) до того, как была осуществлена ​​потоковая загрузка тега a (только тут на странице стало появляться интерактивное отражение загрузки)