1

I searched around but I couldn't find anything useful about this. I'm trying to upload a file to a google cloud bucket in my project using REST APIs, but all i am obtaining is a binary file in the bucket, and not the actual file. Uploading using curl as explained in the Documentation works fine and, e.g., i can upload a png to my bucket. I am using Vue.js and axios to make the request. This is the code for the form:

 <template>
  <div>
    <div id="form">
      <form @submit.prevent="postFiles" enctype="multipart/form-data">
        <input type="file" @change="previewFiles" multiple />
        <input type="submit" value="Send file" />
      </form>
    </div>
  </div>
</template>

<script>
export default {
  name: "InsertFile",
  data() {
    return {
      file: "",
    };
  },
  methods: {
    previewFiles(event) { //I use this just for the debug
      console.log(event.target.files);
      this.file = event.target.files;
    },
    postFiles(){
        this.$emit('insert-file',this.file);
    }
  },
};
</script>

This is the code for the view

<template>
  <div class="upload">
    <h1>Here you can upload your files</h1>
    <InsertFile @insert-file="postFile" />
  </div>
</template>

<script>
import InsertFile from "../components/InsertFile";
import axios from "axios";


let token='exampletoken'
let config = {
  headers: {
    'content-type': 'multipart/form-data',
    Authorization: "Bearer " + token,
    
  },
};

let url =
  "https://storage.googleapis.com/upload/storage/v1/b/bucketURL/o?uploadType=media&name=foo.png";

export default {
  components: {
    InsertFile,
  },
  methods: {
    postFile(path) {
      let bodyFormData = new FormData();
      bodyFormData.append("image", path[0]);
      console.log(bodyFormData);

      axios
        .post(url, bodyFormData, config)
        .then((response) => {
          console.log("Response", response.data);
        })
        .catch((e) => {
          console.log("Error: ", e.response.data);
        });
    },
  },
};
</script>

From this code i obtain a file of type multipart/form-data in the bucket, how can i upload it as a png (or any kind of file)?

[EDIT]

This is the form right now

 <template>
  <div>
    <div id="form">
      <form @submit.prevent="postFiles" enctype="multipart/form-data">
        <input type="file" @change="previewFiles" multiple />
        <input type="hidden" name="Content-Type" value="image/png">
        <input type="submit" value="Send file" />
      </form>
    </div>
  </div>
</template>

This is the method

<script>
    import InsertFile from "../components/InsertFile";
    import axios from "axios";
    
    let url =
      "https://storage.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=media&name=prova.png";
    
    export default {
      components: {
        InsertFile,
      },
      methods: {
        postFile(path) {
          console.log(path);
          let bodyFormData = new FormData();
          bodyFormData.append("file", path[0]);
          bodyFormData.append("content-type", "image/png");
          console.log(bodyFormData);
          let token ='mytoken'
          let config = {
            headers: {
              Authorization: "Bearer " + token,
            },
          };
          axios
            .put(url, bodyFormData, config)
            .then((response) => {
              console.log("Response", response.data);
            })
            .catch((e) => {
              console.log("Error: ", e.response.data);
            });
        },
      },
    };

</script>
cecia234
  • 46
  • 1
  • 6

1 Answers1

0

Within the multipart data you need to send the mime type as a content-type.

For example, with a JPEG you would send Content-Type: image/jpeg

Without this, the upload assumes that the file type is the default of being binary data not an image.

In your link to the docs you provided, take a look at this OBJECT_CONTENT_TYPE part.

To quote their documentation:

The MIME type of the file you are uploading via the form. If you do not specify a content type, the Cloud Storage system defaults to application/octet-stream when it serves the content.

If you are able to, I'd recommend installing and using the storage part of the official NodeJS SDK and following this example here: https://cloud.google.com/storage/docs/uploading-objects#storage-upload-object-nodejs

This should be a lot more robust and provide an immediately functioning example.

It will also make it a lot easier to utilise other functions of the API such as list or delete operations.

Jordan
  • 2,245
  • 6
  • 19
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/220473/discussion-on-answer-by-jordan-uploading-files-to-google-cloud-buckets-using-res). – Samuel Liew Aug 26 '20 at 04:50