1

I am able to upload to Google cloud storage directly using the below form submission ( after getting signed URL using Nodejs )

<form action="https://<%=fields.bucket%>.storage.googleapis.com" method="post" enctype="multipart/form-data">
    <input type="hidden" name="key" value="<%=fields.key%>">
    <input type="hidden" name="bucket" value="<%=fields.bucket%>">
    <input type="hidden" name="GoogleAccessId" value="<%=fields.GoogleAccessId%>">
    <input type="hidden" name="policy" value="<%=fields.policy%>">
    <input type="hidden" name="signature" value="<%=fields.signature%>">
    <input type="hidden" name="Content-Type" value="<%=fields['Content-Type']%>">

    <input name="file" type="file">
    <input type="submit" onclick="myFunction(event)" value="Upload">
</form>

But when using dropzone using the below approach I am getting 400 error . I got my Signed URL successfully and no issues with it . The issue is with axios post method .

 uploadOptions: {
    url: "/",
    uploadMultiple: false,
    method: "PUT",
    parallelUploads: 1,
    headers: {
              "Content-Type": "multipart/form-data"
            },
    autoProcessQueue: false,
    autoDiscover: false,
    acceptedFiles: "image/*",
    maxFilesize: 5,
    maxFiles: 10,
    clickable: "#upload",
    addRemoveLinks: true,
    preventDuplicates: true,
    dictDuplicateFile: "Duplicate Files Cannot Be Uploaded",
    previewsContainer: ".dropzone-previews",
    dictDefaultMessage: "",
    thumbnailWidth: 200,
     accept: function(file, done) {
      var self = this;


      var FileSize = file.size;
      console.log(" In accept");

      k1Object.$axios
        .$get("my-board?operation=fileUpload&name=" + file.name)
        .then(function(gcmData) {
          let postData = gcmData[1];
          let actionURL =
            "https://" + postData.bucket + ".storage.googleapis.com";
          file.uploadURL = actionURL;
          k1Object.k1FormData = gcmData[1];
                    done();
          setTimeout(function() {
          self.processFile(file);
          }, 0)
        });


    }, 
     init: function() {
      var self = this;
      this.on("processing", function(file) {
        self.options.url = file.uploadURL;
        console.log("processing");
      });
      this.on("sending", function(file, xhr, formData) {
        console.log(k1Object.k1FormData.key)
        formData.append("key", k1Object.k1FormData.key);
        formData.append("bucket", k1Object.k1FormData.bucket);
        formData.append("GoogleAccessId", k1Object.k1FormData.GoogleAccessId);
        formData.append("policy", k1Object.k1FormData.policy);
        formData.append("signature", k1Object.k1FormData.signature);
        formData.append("Content-Type", k1Object.k1FormData["Content-Type"]);

         var _send = xhr.send;
        xhr.send = function() {
          _send.call(xhr, file);
        }; 
      });
    } 
  }

400 error

<?xml version='1.0' encoding='UTF-8'?><Error><Code>MissingSecurityHeader</Code><Message>Your request was missing a required header.</Message><Details>Authorization</Details></Error>

I am not sure what fields it is expecting , I did even setup CORS rules for my bucket . Thank You .

Bujji
  • 1,717
  • 10
  • 41
  • 66
  • Hi Bujji, What does GCM represent in this case is it Google Cloud Messaging? Also could you show the code you're using in the smallest reproducible snippet? Thank you! – Frank Natividad Nov 16 '18 at 01:01
  • Thank you @FrankNatividad . I am sorry not sure why I wrote GCM , It is GCS ( Google cloud storage ) . I am posting my axios code above – Bujji Nov 16 '18 at 09:57
  • Thanks @MatrixTai for your comment . I am using XML API and PKCS12 format file . I read somewhere JSON API doesn't support signedURL . Please correct me if I am wrong – Bujji Nov 16 '18 at 12:00
  • @MatrixTai I am totally confused now looking at the documentation . Looks like I have to follow different approach using JWT token . But not sure how to proceed .. Do we have any full example client ( in my case the user who is using my website ) requesting for JWT token through Nodejs for uploading files and using it to upload the files to GCS ..? – Bujji Nov 16 '18 at 17:10
  • You're using the XML API Bujji, I want to clarify that. Bujji you're correct that the JSON API does not support signed URLs. Reviewing the code. Thank you! – Frank Natividad Nov 16 '18 at 22:06
  • Yes, you are correct, I removed my comment, it is not work for Json api. – MT-FreeHK Nov 17 '18 at 06:17
  • I couldn'y find what is the issue with 2MB file issue and so changed the logic and updated the question . For now I am pretty sure the problem is not with any settings in GCS and in getting the signed URL . It is only with the file POST approach . – Bujji Nov 18 '18 at 09:45
  • Bujji@ what is the 400 error message that you see? – Frank Natividad Nov 20 '18 at 18:05
  • @FrankNatividad . Thanks for your response and it is there in the question ( last but one . Here it is any way "MissingSecurityHeaderYour request was missing a required header.
    Authorization
    "
    – Bujji Nov 20 '18 at 21:11
  • @FrankNatividad - I tried almost all the approaches that I am aware of . In the standard approach I am getting that 2MB error and for with above approach in the question "Your request was missing a required header" error – Bujji Nov 21 '18 at 16:40
  • @FrankNatividad :- finally it worked you can not believe the problem . Check this URL for the solution . Placing the file in the end worked . It is seriously crazy . https://stackoverflow.com/questions/16378713/unable-to-upload-file-to-google-cloud-storage-using-post-method – Bujji Jan 01 '19 at 03:18

1 Answers1

0

This post helped me to resolve my issue . Basically what was wrong is that my file input was the first child of the form instead of at the end. Please see the below stackoverflow link for full answer .

https://stackoverflow.com/a/17524079/274715 .

I am still not sure why moving the file to the end helped me .

Bujji
  • 1,717
  • 10
  • 41
  • 66