Как сохранить файл, загружаемый с сервера с помощью react?

у меня есть один бэкэнд API, который в основном загружает шаблон, когда мы его вызываем. Я предоставил href на моей html-странице, поэтому всякий раз, когда кто-то нажимает на этот href, он вызывает backend API, и этот файл должен быть загружен.

но файл не загружается.

Я использую React. Если я просто ударил бэкэнд из своего браузера, файл загружается, но если я вызываю это из react, это не так.

какие-то зацепки?

реагировать Код:

const config = require('config');
var aws4 = require('aws4');
const Promise = require('axios');

const requestHelper = {
  appendHeaders(request){
    request.headers = request.headers || {};
    if(request.headers["Content-Type"]){
      return
    }
    request.headers["Content-Type"] = "application/json";
  },
  externalApi(request, serverResult){
    if(!request.method){
      request.method='POST';
    }
    request.path = request.url
    this.appendHeaders(request)
   console.log('request',request)
    return Promise(request)
    .then((apiResponse) => {
      if (apiResponse.data.errors) {
        var error = apiResponse.data.errors;
        console.log('api error response: ', error);
        serverResult.status(400).json({ error })
      } else {
        console.log('api response: ', apiResponse.data);
        serverResult.status(200).json(apiResponse.data);
      }
    }).catch((error) => {
      console.log('api error response: ', error);
      serverResult.status(400).json({ error });
    });
   },

   getDownloadResponse(request, serverResult){
    debugger;
    request.path = request.url
    this.appendHeaders(request)
    console.log(request);
    return Promise(request)
    .then((apiResponse) => {
      if (apiResponse.data.errors) {
        var error = apiResponse.data.errors;
        console.log('api error response: ', error);
        serverResult.status(400).json({ error })
      } else {
        serverResult.status(200);
        console.log('api response status: '+200);
      }
    }).catch((error) => {
      console.log('api error response: ', error);
      serverResult.status(400).json({ error });
    });
   }
};

module.exports = requestHelper;

КОД API БЭКЭНДА:

@RequestMapping(value = GlobalConstants.DOWNLOAD_FILE, method = RequestMethod.GET)
public void downloadTemplate(HttpServletRequest hRequest, HttpServletResponse response) throws Exception {

    InputStream in = null;
    OutputStream out = null;
    try {
        if (!StringUtils.isEmpty(sampleFile)) {
            File file = new File(sampleFile);
            in = finderService.downloadFile(sampleFile);
            if (in != null) {
                MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();
                response.setContentType(mimetypesFileTypeMap.getContentType(file));
                String headerKey = "Content-Disposition";
                String headerValue = String.format("attachment; filename="%s"", file.getName());
                response.setHeader(headerKey, headerValue);

                out = response.getOutputStream();
                byte[] buffer = new byte[4096];
                int length;
                while ((length = in.read(buffer)) > 0) {
                    out.write(buffer, 0, length);
                }
            }
        } else {
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
        logger.error("Internal Server error"); //Add logs for server error here also

    } catch (Throwable th) {
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        logger.error(th);
        return;
    } finally {
        if (in != null) {
            in.close();
        }
        if (out != null) {
            out.flush();
        }
    }
}

2 ответов


A GET запрос в JS-это не то же самое, что посещение url-адреса в вашем браузере. Вам нужно напрямую вызвать загрузку на клиенте, указав URL-адрес, например:

download() {
  // fake server request, getting the file url as response
  setTimeout(() => {
    const response = {
      file: 'http://releases.ubuntu.com/12.04.5/ubuntu-12.04.5-alternate-amd64.iso',
    };
    // server sent the url to the file!
    // now, let's download:
    window.open(response.file);
    // you could also do:
    // window.location.href = response.file;
  }, 100);
}

вот оно как рабочий пример на JSBin.

Примечание если вы хотите загрузить файлы, которые может отображать браузер (например, JSON, изображения, видео), они будут отображаться на новой вкладке. Если вы хотите, чтобы эти типы файлов загруженных напрямую, вам нужно будет использовать некоторые обходные пути, например, используя blob. Есть несколько примеров такого здесь.


вы можете использовать React 'A' элемент с href и download реквизиты:

 <a href={getFile.url}
    download={getFile.saveAsFileName}>
</a>