简体   繁体   中英

Download file from the server Laravel and reactjs

Hello everybody I'm new in Laravel and reactjs and I have a question, I try to download file from the server to the browser. My request is ok but the file that I wanted is not readable (if I right click on my browser Network->Preview I find symbols and caracters not readable) also the file isn't downloaded. I used visual studio code for coding in windows.

DownloadController:

public function download()
{
    $file = public_path()."/file.pdf";
    return response()->download($file);
}

routes/api.php:

Route::get('download','Api\DownloadController@download');

In the file Js:

import React, { Component } from 'react';
import axios from 'axios';

export default class download extends Component{

    constructor () {
        super();
    }

    componentDidMount() {
            axios.get(`http://127.0.0.1:8000/api/download`)
                .then((response) => {
                    console.log('hello');
                });
    }

    render() {
        return (
            <div>
                <button onClick={this.componentDidMount.bind(this)} className="btn btn-primary">Download</button>
            </div>
        );
    }
}

You must be familiar with axios calls for API consumption, but what about getting the files in response and render those files to the user for download. We got your covered, the below snippet is tested and works well.

axios({
  url: 'http://api.dev/file-download',
  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();
});

Credits to this Javilobo for his useful Solution .

You can check https://github.com/kennethjiang/js-file-download/blob/master/file-download.js to see how to handle IE download stuff.

try to set the correct headers in the laravel download function:

$headers = [
    'Content-Type' => 'application/pdf',
];

return response()->download($file, 'filename.pdf', $headers);

[1] https://stackoverflow.com/a/20415796/592868

You can use header and also conversion before sending contents. These line force browser to download a XML file from my custom collection or model.

$response = Response::create(strval($someCollection), 200);
$response->header('Content-Type', 'text/xml');
$response->header('Cache-Control', 'public');
$response->header('Content-Description', 'File Transfer');
$response->header('Content-Disposition', 'attachment; filename=custome_filename.xml');
$response->header('Content-Transfer-Encoding', 'binary');
return $response;

If your file is ready, no need to read it's content, so you can use this:

return response()->download($pathToFile, $name, $headers);

And $headers can be an array of above example like:

$header = ['Content-Type' => 'text/xml'];

with more custom key => value

There is no need to use Axios or... You can call directly your endpoint URL in your Laravel side, like this in React or pure JS.

window.location.href = window.YOUR_API_DOWNLOAD_URL;

I know the question is about downloading file from laravel through react as a front end, I am posting for those who are in search to download zip file via react (front end) and laravel (backend).

First make controller of your choice... add the following function into laravel controller.

<?php
   
namespace App\Http\Controllers;
   
use Illuminate\Http\Request;
use File;
use ZipArchive;
 

     
    class ZipController extends Controller
    {
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function downloadZip()
        {
            $zip = new ZipArchive;
       
            $fileName = 'myNewFile.zip';
       
            if ($zip->open(public_path($fileName), ZipArchive::CREATE) === TRUE)
            {
                $files = File::files(public_path('myFiles')); //note that this location or folder must exists in order to make the zip file.
       
                foreach ($files as $key => $value) {
                    $relativeNameInZipFile = basename($value);
                    $zip->addFile($value, $relativeNameInZipFile);
                }
                 
                $zip->close();
            }
        
            return response()->download(public_path($fileName));
        }
    }

Now the work of backend is done, in your laravel api route add the below line;

//add it in your routes/api of laravel
Route::get('/zipFileDownload', 'AutosController@downloadZip');

now in react we will work with a file-saver package and fetch request instead of axios.

link: https://www.npmjs.com/package/file-saver

Now make any function according to your choice in react, I am assuming functional component so will write method according to functional component syntax. note before using saveAs function you need to import from the installed package file-saver.

import { saveAs } from 'file-saver';

const downloadZipFileFromLaravel=()=>{
 fetch(`your url/zipFileDownload`)
           
                    .then(res => res.blob())
                    .then(blob => saveAs(blob, 'Auto Photos.zip')) // saveAs is a function from the file-saver package. 
              .catch((err) => {
                console.log(err.message);
              });
}

at the end you need to connect the function with a button with onClick. example

<button onClick={()=>downloadZipFileFromLaravel()}> </button>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM