简体   繁体   中英

Blob is created but File is not uploaded using SignedURL

I am using SignedURL to upload file directly to Cloud Storage without going through App Engine instances. The Process I am following is :

  1. Creating a empty Object and generating a SignedURL for that Object

     Storage storage = null; try{ FileInputStream credentialsStream = new FileInputStream("JSONFile"); Credentials credentials = GoogleCredentials.fromStream(credentialsStream); storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService(); }catch(IOException e) { e.printStackTrace(); } Acl aclObject = Acl.of(User.ofAllUsers(),Role.OWNER); List<Acl> aclAccess = new ArrayList<>(); aclAccess.add(aclObject); //BucketName and User name are Strings. BlobId blobId = BlobId.of(BUCKET_NAME,USER_NAME+"TeamLogo"); BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setAcl(aclAccess).setContentType("image/jpeg").build(); Blob blob = storage.create(blobInfo);

By now , An Empty Object is created in Cloud Storage

在 Cloud Storage 中创建的对象

I am generating a signedURL for this Empty Object such that when user uploads a file , the Content of the file replaces the Empty object

    HttpMethod httpMethod = HttpMethod.PUT;

    ServiceAccountSigner signer = ServiceAccountCredentials.newBuilder().setClientId(CLIENT_ID).setClientEmail(CLIENT_EMAIL).setPrivateKey(PRIVATEKEY).setPrivateKeyId(PRIVATE_KEY_ID).build()

    URL url = blob.signUrl(10,TimeUnit.MINUTES,Storage.SignUrlOption.httpMethod(httpMethod),Storage.SignUrlOption.signWith(signer),Storage.SignUrlOption.withContentType());
    return url;

My HTML code to handle the Upload of the File

 <form action="${signedURL}" method="put" enctype="multipart/form-data"> <label>Enter Your User Name</label><br> <input type="text" name="UserName" ><br><br> <label>Enter Your Team Name</label><br> <input type="text" name="TeamName" ><br><br> <label>Upload Team Logo</label><br> <input type="file" name="myFile" required="required"><br><br> <input type="submit" value="Create Team"> <input type="hidden" name="success_action_redirect" value="http://localhost:8080/register"> </form>

After selecting the file and Clicking on Upload, the file I selected is not uploaded to Cloud Storage and it is loading this page ( A white page with a URL).

输出图像

I am not achieving my desired result. What I am missing in my Code ? Java Documentation for Cloud Storage doesn't offer full picture for newbies like me. Someone please help me in this regard.

UPDATE : Javascript AJAX Request to Cloud Storage

 var signedURL; function uploadFile(){ var urlxhr = new XMLHttpRequest(); //To get the SignedURL from server side urlxhr.open('GET','http://localhost:8080/getsignedurl') urlxhr.send(); urlxhr.onreadystatechange = function(){ if (urlxhr.readyState == 4 && urlxhr.status == 200) { signedURL = urlxhr.responseText; var file = document.getElementById("myFile").files[0] var formData = new FormData(); formData.append('imageFile',file); var storageXhr = new XMLHttpRequest(); storageXhr.open('PUT',signedURL,true); storageXhr.onload = () => { if(storageXhr.status == 200){ alert("File Successfully Uploaded"); }else{ alert("Something went Wrong"); } }; storageXhr.onerror = () => { alert("An Error occured while Uploading file"); }; storageXhr.setRequestHeader('Content-Type',file.type); storageXhr.send(formData); } } }
 <!-- Uploading Directly to Cloud storage by AJAX Request --> <form action="#" method="put" onsubmit="uploadFile()"> <label>Select Your Team Logo</label> <input type="file" id="myFile" required="required"> <input type="submit" value="Upload File"> </form> </div>

It looks like you're trying to use the POST Object command but using thePUT Object command. For example, you're using the success_action_redirect , which is only a thing for the POST object command. The PUT Object command doesn't accept form-data in this fashion.

You can use the PUT object command with a signed URL, but not in this fashion. Instead, you'd use JavaScript to craft an upload of a file's contents.

The POST object command is the one you want if you plan to use an HTML form. The rules for signing those requests are a bit different, though. Check out the "policy document" section of the documentation: https://cloud.google.com/storage/docs/xml-api/post-object#usage_and_examples

So, to change the example above, switch the method to POST , add a policy field and a Signature field that is crafted by the server the same way you're signing your requests now, and switch the action to ' https://storage.googleapis.com/bucket_name '.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM