Прямая загрузка файла клиента vue с сервера node js не работает

Хорошо, поэтому я уже 2 дня пытаюсь отправить аудиофайл в виде прямой загрузки в браузере с бэкэнда node js (порт 8081) на клиентский интерфейс vue js (порт 8080) по http-запросу (используя axios) .

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

Мой браузер/клиент получает ответ, но не переводит его на прямую загрузку, вот как это выглядит:

{data: "ID3#TSSELavf57.71.100���…UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU", status: 200, statusText: "OK", headers: {…}, config: {…}, …}
config: {url: "http://localhost:8081/api/tracks/download/5df305bc6cea85c8eac5d3e6", method: "get", headers: {…}, transformRequest: Array(1), transformResponse: Array(1), …}
data: "ID3#TSSELavf57.71.100���..."
headers: {cache-control: "public, max-age=0", content-length: "9775064", content-type: "audio/mpeg", last-modified: "Fri, 13 Dec 2019 03:30:04 GMT"}
request: XMLHttpRequest {readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
status: 200
statusText: "OK"
__proto__: Object

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

Вот коды:

маршрут загрузки сервера node.js

router.get('/download/:id', async (req, res) => {
  const tracks = await loadTracksCollection();
  var id = new mongodb.ObjectID(req.params.id);
  var track = await tracks.findOne({ _id: id });
  var trackPath = String(track.path);
  var trackName = String(track.user + ' - ' + track.name + '.mp3');
  res.download(trackPath, trackName, (err) => {
    if (err) {
      console.error(err);
      return ;
    } else {
    tracks.updateOne({ _id: id }, { $inc: { downloadCount: 1 } });
    // return res.status(200).send('The download should start ...')
    }
  });
});

компонент кнопки vue.js

<template>
  <v-btn @click="download" depressed block color="accent"><unicon name="import" fill="white" /></v-btn>
</template>

<script>
import axios from 'axios'

export default {
  props: {
    fileId: {
      required: true,
      type: String
    }
  },
  methods: {
    download() {
      axios.get(process.env.VUE_APP_AUDIO_API_URL + '/api/tracks/download/' + this.fileId)
           .then(response => {
             console.log(response)
           })
           .catch(error => {
             console.error(error)
           })
    }
  }
}
</script>

дайте мне знать, если нужен код!

Большое спасибо !


person Oscar Fally    schedule 13.12.2019    source источник


Ответы (2)


Вам нужно изменить responseType в axios...

axios({
    method: 'GET',
    url: process.env.VUE_APP_AUDIO_API_URL + '/api/tracks/download/' + this.fileId,
    responseType: 'arraybuffer'
}).then(response => {
   console.log(response.data)
}).catch(error => {
   console.error(error)
})
person Zim    schedule 13.12.2019
comment
Привет, спасибо, что ответили мне! Только что попробовал это, и инструменты разработчика теперь утешают это: ArrayBuffer(440651) {} ... (с кучей массивов int), но прямой загрузки не происходит - person Oscar Fally; 13.12.2019

Хорошо, тема кажется сложной, но я нашел свое решение, вот и все:

      this.$axios({
          method: 'GET',
          url: // ur backend api url,
          responseType: 'arraybuffer'
        })
        .then(response => {
          var blob = new Blob([response.data], {type: response.headers['content-type']})
          var link = document.createElement('a')
          link.href = window.URL.createObjectURL(blob)
          link.download = // name the downloaded file
          link.click()
        })
        .catch(error => { 
          // whatever
        })
        .finally(() => {
          // whatever
        }

person Oscar Fally    schedule 18.12.2019