Синатра отправляет поврежденный .zip файл с `send_file`, когда я пытаюсь скачать с React - PullRequest
0 голосов
/ 15 января 2020

Итак, в моем проекте Sinatra я создаю файл .zip с несколькими песнями, а затем хочу вернуть этот файл как ответ с помощью send_file helper. И когда я пытаюсь загрузить файл с React в front-end, он загружает что-то, но он говорит, что это неверный формат или поврежден.

Это код, который у меня есть в Синатре:

def download_songs(song_list)    
    time = Time.new
    temp_dir_name = rand(100000..999999).to_s + time.strftime("%d%m%Y%H%M%S")
    Dir.mkdir(temp_dir_name)
    song_list.each { |song|
        formatted_command = 'youtube-dl -o "' + __dir__.to_s + '/' + temp_dir_name + '/%(title)s.%(ext)s" -x --audio-format mp3 "ytsearch:' + song + '"'
        system formatted_command
    }

    zipfile_name = "#{__dir__.to_s}/#{temp_dir_name}/YourSongs.zip"
    folder_to_zip = "#{__dir__.to_s}/#{temp_dir_name}"
    file_names = Dir.children(temp_dir_name)

    Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
        file_names.each do |filename|
            zipfile.add(filename, File.join(folder_to_zip, filename))
        end
    end    

    file_to_send_to_front = "./" + temp_dir_name + "/YourSongs.zip"
    send_file file_to_send_to_front, :filename => "YourSongs.zip", :type => 'application/octet-stream'
end

И я вызываю эту функцию в этом фрагменте кода:

post '/download' do
    content_type :json
    all_songs_to_download = params['songs'].split(',')
    download_songs(all_songs_to_download)        
end

И когда он загружает ее локально на сервер. Я могу открыть его как обычно, поэтому я бы сказал, что Zip создается не правильно, но React загружает его неправильно или send_file отправляет его неправильно. Кстати, я попытался отправить обычный файл README.md таким же образом, и он работал нормально.

И вот код в React, который я использую для загрузки файла .zip:

_downloadSongs = () => {

        let data = new FormData();
        data.append('songs', this.state.songs);

        axios({
            method: "POST",
            url: 'http://localhost:4567/download',
            data: data,
            headers: {'Content-Type': 'multipart/form-data'}
        }).then(res => {
            fileDownload(res.data, 'YourSongs.zip');
        }).catch(err => {
            console.log(err)
        })
    }

ПРИМЕЧАНИЕ : Я использую js -file-download для загрузки файла, полученного мной в ответ от Синатры.

1 Ответ

4 голосов
/ 15 января 2020

Вы пытались установить следующее в send_file:

:type => 'application/zip',
:disposition => 'attachment'
...