Как скачать файл в React JS

Я получаю URL-адрес файла в качестве ответа от api. когда пользователь нажимает кнопку загрузки, файл должен быть загружен без открытия предварительного просмотра файла в новой вкладке. Как этого добиться в React JS?

Запуск загрузки браузера из внешнего интерфейса - ненадежный способ сделать это. Вы должны создать конечную точку, которая при вызове будет предоставлять правильные заголовки ответа, тем самым инициируя загрузку браузера. Фронтенд-код может не так много. Например, атрибут «загрузка» может просто открыть файл в новой вкладке в зависимости от браузера.

Jackyef 05.06.2018 10:08

Насколько я понимаю, вы говорите, что этого можно достичь с помощью rest api с правильными заголовками ответов, верно?

Sameer Thite 05.06.2018 10:15

Да. Я не знал, как прикрепить ссылку в комментарии, поэтому опубликовал ответ.

Jackyef 05.06.2018 10:20
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
91
3
265 962
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

Это не связано с React. Однако вы можете использовать атрибут download в элементе привязки <a>, чтобы указать браузеру загрузить файл.

<a href='/somefile.txt' download>Click to download</a>

Это поддерживается не во всех браузерах: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a

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

Sameer Thite 05.06.2018 10:08

Обратитесь к этому для получения более подробной информации: stackoverflow.com/questions/2408146/…

lipp 05.06.2018 10:19
download соблюдает политику одного и того же происхождения FYI
user 04.12.2020 05:13
Ответ принят как подходящий

Запускать загрузку браузера из внешнего интерфейса ненадежно.

Что вам нужно сделать, так это создать конечную точку, которая при вызове будет предоставлять правильные заголовки ответов, тем самым инициируя загрузку браузера.

Фронтенд-код может не так много. Например, атрибут «загрузка» может просто открыть файл в новой вкладке в зависимости от браузера.

Заголовки ответов, на которые вам нужно обратить внимание, вероятно, это Content-Type и Content-Disposition. Вы должны проверить этот отвечать для более подробного объяснения.

Что вам следует сделать, так это создать конечную точку, которая при вызове будет предоставлять правильные заголовки ответов, тем самым инициируя загрузку браузера ... Что это за заголовки и как специфические заголовки могут запускать загрузку браузера? Благодарность

1020rpz 22.05.2020 18:46

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

после получения ссылки на файл из api просто используйте простой javascript, создав тег привязки, и удалите его после динамического щелчка сразу на лету.

const link = document.createElement('a');
link.href = `your_link.pdf`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);

За исключением того, что браузер откроет PDF-файл, и я хочу, чтобы он загрузился. Не открыто.

Jake 31.07.2020 15:46

Он также работает с реакцией и узлом / HAPI. Я добавил ниже link.href = your_link.pdf; link.download = yourFileName; Большое спасибо.

Pankaj 29.10.2020 17:36

Если вы используете React Router, используйте это:

<Link to = "/files/myfile.pdf" target = "_blank" download>Download</Link>

Где /files/myfile.pdf находится внутри вашей папки public.

Я пытаюсь создать zip-файл, файл загружается и никогда не распаковывает его должным образом. Кто-то может знать причину этого? Кстати, я нашел обходной путь: stackoverflow.com/a/62855917/7622204

Rohan Kumar 12.07.2020 02:27

Вы можете определить компонент и использовать его где угодно.

import React from 'react';
import PropTypes from 'prop-types';


export const DownloadLink = ({ to, children, ...rest }) => {

  return (
    <a
      {...rest}
      href = {to}
      download
    >
      {children}
    </a>
  );
};


DownloadLink.propTypes = {
  to: PropTypes.string,
  children: PropTypes.any,
};

export default DownloadLink;

React создает проблему безопасности при использовании тега a с target = "_blank".

Мне удалось заставить его работать вот так:

<a href = {uploadedFileLink} target = "_blank" rel = "noopener noreferrer" download>
   <Button>
      <i className = "fas fa-download"/>
      Download File
   </Button>
</a>

Вот как я это сделал в React:

import MyPDF from '../path/to/file.pdf';
<a href = {myPDF} download = "My_File.pdf"> Download Here </a>

Важно переопределить имя файла по умолчанию с помощью download = "name_of_file_you_want.pdf", иначе файл получит хэш-номер, прикрепленный к нему при загрузке.

У меня точно такая же проблема, и вот решение, которым я сейчас пользуюсь: (Заметьте, мне это кажется идеальным, потому что он сохраняет файлы, тесно связанные с приложением SinglePageApplication React, которое загружается из Amazon S3. Таким образом, это похоже на хранение на S3 и в приложении, которое знает, где оно находится в S3, относительно говоря .

Шаги

3 шага:

  1. Используйте файловую заставку в проекте: npmjs / пакет / хранитель файлов (npm install file-saver или что-то в этом роде)
  2. Поместите файл в свой проект Вы говорите, что это в папке компонентов. Что ж, есть вероятность, что если у вас есть веб-пакет, он попытается его минимизировать. (Кто-нибудь, пожалуйста, укажите, что веб-пакет будет делать с файлом ресурсов в папке компонентов), и поэтому я не думаю, что это то, что вам нужно. . Итак, я предлагаю поместить актив в папку public под именем resource или asset. Webpack не касается папки public и index.html, и ваши ресурсы копируются в производственную сборку как есть, где вы можете ссылаться на них, как показано на следующем шаге.
  3. Обратитесь к файлу в вашем проекте Пример кода:
    import FileSaver from 'file-saver';
    FileSaver.saveAs(
        process.env.PUBLIC_URL + "/resource/file.anyType",
        "fileNameYouWishCustomerToDownLoadAs.anyType");
    

Источник

Приложение

Это классная библиотека. К сожалению, он по-прежнему открывал PDF-файлы в новой вкладке. Тем не менее, это делает открытие файла на лету действительно чистым процессом.

Jake 31.07.2020 15:57

Вы можете использовать FileSaver.js для достижения этой цели:

const saveFile = () => {
fileSaver.saveAs(
  process.env.REACT_APP_CLIENT_URL + "/resources/cv.pdf",
  "MyCV.pdf"
);

};

<button className = "cv" onClick = {saveFile}>
    Download File
</button>

Он откроет pdf в новой вкладке при использовании FileSaver

Divyesh Kanzariya 18.11.2020 05:47

@DivyeshKanzariya, как решить этот вопрос?

mikkylekyle 07.04.2021 04:37

tldr; получить файл с URL-адреса, сохранить его как локальный Blob, вставить элемент ссылки в DOM и щелкнуть его, чтобы загрузить Blob

У меня был файл PDF, который хранился в S3 за URL-адресом Cloudfront. Я хотел, чтобы пользователь мог нажать кнопку и немедленно инициировать загрузку, не открывая новую вкладку с предварительным просмотром PDF. Как правило, если файл размещен по URL-адресу, домен которого отличается от домена, на котором в настоящее время находится пользователь, немедленная загрузка блокируется многими браузерами из соображений безопасности пользователя. Если вы используете это решение, не инициирует загрузку файла, если пользователь не нажимает кнопку для преднамеренной загрузки.

Чтобы справиться с этим, мне нужно было получить файл по URL-адресу, обойдя любые политики CORS, чтобы сохранить локальный Blob-объект, который затем стал бы источником загруженного файла. В приведенном ниже коде убедитесь, что вы заменили свои собственные fileURL, Content-Type и FileName.

fetch('https://cors-anywhere.herokuapp.com/' + fileURL, {
    method: 'GET',
    headers: {
      'Content-Type': 'application/pdf',
    },
  })
  .then((response) => response.blob())
  .then((blob) => {
    // Create blob link to download
    const url = window.URL.createObjectURL(
      new Blob([blob]),
    );
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute(
      'download',
      `FileName.pdf`,
    );

    // Append to html link element page
    document.body.appendChild(link);

    // Start download
    link.click();

    // Clean up and remove the link
    link.parentNode.removeChild(link);
  });

Это решение ссылается на решения получение большого двоичного объекта из URL-адреса и с использованием прокси-сервера CORS.

Обновлять Начиная с 31 января 2021 г., демонстрация cors -where, размещенная на серверах Heroku, разрешает только ограниченное использование в целях тестирования и не может использоваться для производственных приложений. Вам нужно будет разместить свой собственный сервер cors -where, следуя корс везде или корс-сервер.

большое спасибо :) работает как шарм

KMR 07.01.2021 14:29

Решение (Идеально подходит для React JS, Next JS)

Вы можете использовать js-файл-загрузка, и это мой пример:

import axios from 'axios'
import fileDownload from 'js-file-download'
 
...

handleDownload = (url, filename) => {
  axios.get(url, {
    responseType: 'blob',
  })
  .then((res) => {
    fileDownload(res.data, filename)
  })
}
 
...

<button onClick = {() => {this.handleDownload('https://your-website.com/your-image.jpg', 'test-download.jpg')
}}>Download Image</button>

Этот плагин может загружать Excel и другие типы файлов.

это работает хорошо, просит сохранить как, это то, что я искал

Santhosh 26.03.2021 10:20

Я не могу открыть файл после загрузки. Ошибка файла: «Не удалось открыть файл (nameFile). Возможно, он поврежден или использует формат файла, который не распознается программой Preview». Я что-нибудь пропустил?

hoanghuychh 30.03.2021 12:52

Наконец, спасибо !!!

Brandon Austin 01.06.2021 20:56

Мы можем использовать компонент response-download-link для загрузки контента в виде файла.

<DownloadLink
label = "Download"
filename = "fileName.txt"
exportFile = {() => "Client side cache data here…"}/>

https://frugalisminds.com/how-to-download-file-in-react-js-react-download-link/

Скачать файл


Для загрузки вы можете использовать несколько способов, как описано выше, кроме того, я также предоставлю свою стратегию для этого сценария.

  1. npm install --save react-download-link
  2. import DownloadLink from "react-download-link";
  3. Ссылка для загрузки React для данных кеша на стороне клиента
    <DownloadLink 
        label = "Download" 
        filename = "fileName.txt"
        exportFile = {() => "Client side cache data here…"}
    />
    
  4. Ссылка для скачивания данных кеша на стороне клиента с помощью обещаний
    <DownloadLink
        label = "Download with Promise"
        filename = "fileName.txt"
        exportFile = {() => Promise.resolve("cached data here …")}
    />
    
  5. Ссылка для загрузки данных из URL-адреса с функцией обещаний для извлечения данных из URL-адреса
     getDataFromURL = (url) => new Promise((resolve, reject) => {
        setTimeout(() => {
            fetch(url)
                .then(response => response.text())
                .then(data => {
                    resolve(data)
                });
        });
    }, 2000);
    
  6. Компонент DownloadLink вызывает функцию Fetch
    <DownloadLink
          label=”Download”
          filename=”filename.txt”
          exportFile = {() => Promise.resolve(this. getDataFromURL (url))}
    />
    

Удачного кодирования! ;)

fetchFile(){
  axios({
        url: `/someurl/thefiles/${this.props.file.id}`,
        method: "GET",
        headers: headers,
        responseType: "blob" // important
    }).then(response => {
        const url = window.URL.createObjectURL(new Blob([response.data]));
        const link = document.createElement("a");
        link.href = url;
        link.setAttribute(
            "download",
            `${this.props.file.name}.${this.props.file.mime}`
        );
        document.body.appendChild(link);
        link.click();
    });
}
render(){
  return( <button onClick = {this.fetchFile}> Download file </button>)
}

Другие вопросы по теме