简体   繁体   English

已创建 Blob,但未使用 SignedURL 上传文件

[英]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.我正在使用 SignedURL 将文件直接上传到 Cloud Storage,而无需通过 App Engine 实例。 The Process I am following is :我遵循的过程是:

  1. Creating a empty Object and generating a SignedURL for that Object创建一个空对象并为该对象生成一个 SignedURL

     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 中创建了一个空对象

在 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我正在为这个空对象生成一个签名 URL,这样当用户上传文件时,文件的内容会替换空对象

    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我处理文件上传的 HTML 代码

 <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).选择文件并点击上传后,我选择的文件没有上传到云存储,它正在加载这个页面(一个带有 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. Cloud Storage 的 Java 文档并没有为像我这样的新手提供全貌。 Someone please help me in this regard.有人请在这方面帮助我。

UPDATE : Javascript AJAX Request to Cloud Storage更新:对云存储的 Javascript AJAX 请求

 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.看起来您正在尝试使用POST Object命令但使用PUT Object命令。 For example, you're using the success_action_redirect , which is only a thing for the POST object command.例如,您正在使用success_action_redirect ,这仅适用于 POST 对象命令。 The PUT Object command doesn't accept form-data in this fashion. PUT Object 命令不以这种方式接受表单数据。

You can use the PUT object command with a signed URL, but not in this fashion.您可以使用带有签名 URL 的 PUT 对象命令,但不能以这种方式使用。 Instead, you'd use JavaScript to craft an upload of a file's contents.相反,您将使用 JavaScript 来制作文件内容的上传。

The POST object command is the one you want if you plan to use an HTML form.如果您打算使用 HTML 表单,那么 POST 对象命令就是您想要的命令。 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查看文档的“政策文档”部分: 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 '.因此,要更改上面的示例,请将方法切换为POST ,添加由服务器制作的policy字段和Signature字段,与您现在签署请求的方式相同,然后将操作切换为 ' https://storage .googleapis.com/bucket_name '。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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