Вопрос по reactjs, axios –  следовательно, странные аннотации, однако, это решение не зависит от структуры. Идея подойдет для любого дизайна на основе HTML.

21

ользую axios для базовых http-запросов, таких как get и post, и это хорошо работает. Теперь мне нужно иметь возможность загружать файлы Excel тоже. Это возможно с axios. Если да, у кого-нибудь есть пример кода? Если нет, что еще я могу использовать в приложении реагирования, чтобы сделать то же самое?

Да, так как вы можете генерировать заголовки HTTP-запросов, которые вам нравятся. Проверь это:blog.bguiz.com/2014/07/03/... prosti

Ваш Ответ

6   ответов
35

заголовки ответа будут выглядеть примерно так:

Content-Disposition: "attachment;filename=report.xls"
Content-Type: "application/octet-stream" // or Content-type: "application/vnd.ms-excel"

Что вы можете сделать, это создать отдельный компонент, который будет содержать скрытый iframe.

  import * as React from 'react';

  var MyIframe = React.createClass({

     render: function() {
         return (
           <div style={{display: 'none'}}>
               <iframe src={this.props.iframeSrc} />
           </div>
         );
     }
  });

Теперь вы можете передать URL-адрес загружаемого файла в качестве опоры этому компоненту, поэтому, когда этот компонент получит опору, он будет перерисован и файл будет загружен.

Редактировать: Вы также можете использоватьJS-файлов скачать модуль.Ссылка на репозиторий Github

const FileDownload = require('js-file-download');

Axios.get(`http://localhost/downloadFile`)
   .then((response) => {
        FileDownload(response.data, 'report.csv');
   });

Надеюсь это поможет :)

@DavidChoi Это сработало? Hardik Modha
Спасибо. Можете ли вы сказать мне, если это в стиле AJAX. Было бы хорошо, чтобы не заблокировать страницу. David Choi
Как уже упоминалось вэтот ответ. В объекте ответа axios, внутри запроса есть поле с именем AsresponseURL, может быть, это URL, который вы хотите. Hardik Modha
Да, Страница не будет заблокирована. Когда вы передадите URL-адрес этому компоненту, файл будет загружен автоматически. Вам не нужно ничего делать. Hardik Modha
Еще один вопрос. В моем случае загружаемый файл создается динамически с некоторыми переданными параметрами. Так что на самом деле не имеет постоянного местоположения. Какой URL я отправляю для этого типа сценария? Например, если я назвал axios.post ('api / getmyexcelfile', params); David Choi
-4

Мой ответполный взлом- Я только что создал ссылку, похожую на кнопку, и добавил к ней URL.

<a class="el-button"
  style="color: white; background-color: #58B7FF;"
  :href="<YOUR URL ENDPOINT HERE>"
  :download="<FILE NAME NERE>">
<i class="fa fa-file-excel-o"></i>&nbsp;Excel
</a>

Я пользуюсь отличноVueJs следовательно, странные аннотации, однако, это решение не зависит от структуры. Идея подойдет для любого дизайна на основе HTML.

0
        axios.get(
            '/app/export'
        ).then(response => {    
            const url = window.URL.createObjectURL(new Blob([response]));
            const link = document.createElement('a');
            link.href = url;
            const fileName = `${+ new Date()}.csv`// whatever your file name .
            link.setAttribute('download', fileName);
            document.body.appendChild(link);
            link.click();
            link.remove();// you need to remove that elelment which is created before.
})
8

Более общее решение

axios({
  url: 'http://api.dev/file-download', //your url
  method: 'GET',
  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', 'file.pdf'); //or any other extension
   document.body.appendChild(link);
   link.click();
});

Проверьте причуды вhttps://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743

Полные кредиты для:https://gist.github.com/javilobo8

Спасибо за решение. Несколько замечаний для других: хотя это может работать для многих случаев использования, но для файлов большого размера вы не сможете увидеть ход загрузки. И это займет дополнительную память в браузере. Как упоминалось в других решениях, но не прописано, общий подход заключается в использовании заголовка «Content-Disposition: attachment;» поэтому браузер будет воспринимать его как собственную загрузку (вышеупомянутый процесс загрузки + прямая загрузка на диск). John Lee
0

чтобы сделать невидимый тег привязки вrender() и добавить Реактref позволяя вызвать клик, как только мы получим ответ axios:

class Example extends Component {
    state = {
        ref: React.createRef()
    }

    exportCSV = () => {
        axios.get(
            '/app/export'
        ).then(response => {
            let blob = new Blob([response.data], {type: 'application/octet-stream'})
            let ref = this.state.ref
            ref.current.href = URL.createObjectURL(blob)
            ref.current.download = 'data.csv'
            ref.current.click()
        })
    }

    render(){
        return(
            <div>
                <a style={{display: 'none'}} href='empty' ref={this.state.ref}>ref</a>
                <button onClick={this.exportCSV}>Export CSV</button>
            </div>
        )
    }
}

Вот документация:https://reactjs.org/docs/refs-and-the-dom.html, Вы можете найти похожую идею здесь:https://thewebtier.com/snippets/download-files-with-axios/.

26
Загрузка файлов (используя Axios и Security)

когда вы хотите загружать файлы с помощью Axios и некоторых средств безопасности. Чтобы никто не потратил слишком много времени на выяснение этого, позвольте мне рассказать вам об этом.

Вам нужно сделать 3 вещи:

1. Configure your server to permit the browser to see required HTTP headers
2. Implement the server-side service, and making it advertise the correct file type for the downloaded file.
3. Implementing an Axios handler to trigger a FileDownload dialog within the browser

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

1. Настройте ваш (HTTP) сервер

При использовании безопасности транспорта JavaScript, выполняемый в браузере, может [по замыслу] получить доступ только к 6 из заголовков HTTP, фактически отправленных сервером HTTP. Если мы хотим, чтобы сервер предложил имя файла для загрузки, мы должны сообщить браузеру, что «нормально», чтобы JavaScript предоставил доступ к другим заголовкам, в которые будет перенесено предлагаемое имя файла.

Предположим, ради обсуждения, что мы хотим, чтобы сервер передавал предложенное имя файла в заголовке HTTP с именемX-Отдается-файл, HTTP-сервер сообщает браузеру, что этоХорошо чтобы выставить этот полученный пользовательский заголовок в JavaScript / Axios со следующим заголовком:

Access-Control-Expose-Headers: X-Suggested-Filename

Точный способ настройки HTTP-сервера для установки этого заголовка зависит от продукта.

Увидетьhttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers для полного объяснения и подробного описания этих стандартных заголовков.

2. Внедрить серверную службу

Ваша реализация службы на стороне сервера теперь должна выполнять 2 вещи:

1. Create the (binary) document and assign correct ContentType to the response
2. Assign the custom header (X-Suggested-Filename) containing the suggested file name for the client

Это делается по-разному в зависимости от выбранного вами технологического стека. Я нарисую пример с использованием стандарта JavaEE 7, который должен генерировать отчет Excel:

@GET
@Path("/report/excel")
@Produces("application/vnd.ms-excel")
public Response getAllergyAndPreferencesReport() {

    // Create the document which should be downloaded
    final byte[] theDocumentData = .... 

    // Define a suggested filename
    final String filename = ... 

    // Create the JAXRS response
    // Don't forget to include the filename in 2 HTTP headers: 
    //
    // a) The standard 'Content-Disposition' one, and
    // b) The custom 'X-Suggested-Filename'  
    //
    final Response.ResponseBuilder builder = Response.ok(
            theDocumentData, "application/vnd.ms-excel")
            .header("X-Suggested-Filename", fileName);
    builder.header("Content-Disposition", "attachment; filename=" + fileName);

    // All Done.
    return builder.build();
}

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

3. Реализовать обработчик Axios для полученного документа.

Здесь есть несколько подводных камней, поэтому давайте убедимся, что все детали правильно настроены:

Служба отвечает на @GET (т.е. HTTP GET), поэтому вызов axios должен быть «axios.get (...)».Документ передается в виде потока байтов, поэтому вы должны указать axios обработать ответ как BLOB-объект HTML5. (Т.е.responseType: 'blob').В этом случае библиотека JavaScript для сохранения файлов используется для открытия диалогового окна браузера. Тем не менее, вы можете выбрать другой.

Тогда скелетная реализация Axios будет выглядеть примерно так:

 // Fetch the dynamically generated excel document from the server.
 axios.get(resource, {responseType: 'blob'}).then((response) => {

    // Log somewhat to show that the browser actually exposes the custom HTTP header
    const fileNameHeader = "x-suggested-filename";
    const suggestedFileName = response.headers[fileNameHeader];'
    const effectiveFileName = (suggestedFileName === undefined
                ? "allergierOchPreferenser.xls"
                : suggestedFileName);
    console.log("Received header [" + fileNameHeader + "]: " + suggestedFileName
                + ", effective fileName: " + effectiveFileName);

    // Let the user save the file.
    FileSaver.saveAs(response.data, effectiveFileName);

    }).catch((response) => {
        console.error("Could not Download the Excel report from the backend.", response);
    });
Это работает, но рекомендуется использоватьcontent-disposition заголовок вместоx-suggested-filename. Rosdi Kasim
Что такое FileSaver? Main Pal
Это библиотека для обработки загружаемых файлов,github.com/eligrey/FileSaver.js/#filesaverjs Radi

Похожие вопросы