Vue-resource: Force downolad a file

Created on 5 Jun 2016  Â·  9Comments  Â·  Source: pagekit/vue-resource

I'm sending a request that send back a file to download with Content-Disposition:attachment;, however vue-resource is getting it as a string and is not downloading the file.

Any idea how can i force download the file instead?

Most helpful comment

Found this: http://stackoverflow.com/a/35851873

$http.post(
  'url',
  {},
  {responseType: 'arraybuffer'}
).then(function (response) {
  var headers = response.headers();
  var blob = new Blob([response.data],{type:headers['content-type']});
  var link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = "Filename";
  link.click();
});

so three things:

  1. As a developer for your proejct, you've chosen to use vue-resource. Have you defined for your client and had them sign off on a list of browser you aim to support?
  2. is Blob supported in that list of browsers?
  3. most importantly, does vue-resource allow us to set responseType?

All 9 comments

That's what I did but I had to use get instead of post
On Jun 7, 2016 12:56 PM, "Guillaume" [email protected] wrote:

You just have to do a window.open(url) to force download, as long as you
have proper response headers

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/vuejs/vue-resource/issues/285#issuecomment-224234227,
or mute the thread
https://github.com/notifications/unsubscribe/AAT-iRypnbv_Y-ibKLNkyy1S3f9xRMZqks5qJUBHgaJpZM4IuR7d
.

I have the same problem. I need to do a POST request to a server and the server responds with a file download. In jQuery is pretty easy to do that with processData: false. How can we do that in vue-resource?

Server return filePath,and 'window.location = filePath' in callback

Found this: http://stackoverflow.com/a/35851873

$http.post(
  'url',
  {},
  {responseType: 'arraybuffer'}
).then(function (response) {
  var headers = response.headers();
  var blob = new Blob([response.data],{type:headers['content-type']});
  var link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = "Filename";
  link.click();
});

so three things:

  1. As a developer for your proejct, you've chosen to use vue-resource. Have you defined for your client and had them sign off on a list of browser you aim to support?
  2. is Blob supported in that list of browsers?
  3. most importantly, does vue-resource allow us to set responseType?

So it works like this:

// ./api/index.js
const client = Vue.http;

export function form(data) {
  return client.post('/api/foo', { bar: 'baz'})
    .then( (response) => {
      let blob = new Blob([response.blob()], {type: response.headers['content-type']}),
          filename = (response.headers['Content-Disposition'] || '').split('filename=')[1];
          result = document.createElement('a');
          result.href = window.URL.createObjectURL(blob);
          result.download = filename;
          return result;
  });
}
// ./root.vue
import * as api from './api';

export default {
  methods: {
    getForm () {
      let data = JSON.parse(JSON.stringify(this.$get('form')));
      api.form(data)
        .then((link) => { link.click(); })
    }
  }
};

@airtonix Works, but with zips always save a corrupt file.

My solution: https://gist.github.com/11joselu/2096717e444849b597a5a2e3f2080eaf

I am using var blob = new Blob(...) or var files = new File(...) to download a file from API, but i get an error Blob is not defined, there's anyone know how to resolve this problem?

This solution works for me without any form of file corruption.

    async download(){
        let response = await Vue.http.get("file/download/" + this._id, {responseType: 'arraybuffer'});
        let blob = new Blob([response.data], {type:response.headers.get('content-type')});
        let link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download = this.name;
        link.click();
    }

The responseType is very important. Otherwise only txt files will work. By setting responseType to arrayBuffer, all file types are converted correctly.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

facesea picture facesea  Â·  5Comments

laizhenhai88 picture laizhenhai88  Â·  4Comments

Jigsaw5279 picture Jigsaw5279  Â·  5Comments

jiyifun picture jiyifun  Â·  3Comments

odranoelBR picture odranoelBR  Â·  6Comments