Google-cloud-php: Signed URL Upload Incomplete & Breaks CORS

Created on 17 Dec 2018  路  2Comments  路  Source: googleapis/google-cloud-php

I want to sign-upload a new object to a bucket with XHR but can't. This is because the bucket CORS origin policy does not load when the upload url is /$bucket/$key instead of /$bucket.

The signedUploadURL method exists on the StorageObject class and not the Bucket class. It also seems to forcefully start a resumable upload, which is not my use case.

storage question

All 2 comments

Hi @vbresults,

The easiest way to do a non-resumable XHR upload to a signed URL will be with the HTTP PUT method via StorageObject::signedUrl().

Because you must specify the file name and any metadata ahead of time, the signed URL methods exist on the StorageObject class. You can instantiate a StorageObject instance for a non-existent object with no trouble, but certain methods which rely on the object existing will of course not work until the object has been created.

The below example demonstrates the full process in PHP. I also tested using XMLHttpRequest on Google AppEngine and verified that the upload succeeds with CORS enabled on the bucket, and fails when I remove my AppEngine domain from the CORS policy.

Please give this a try using StorageObject::signedUrl() with a PUT method and let me know how it works.

use Google\Cloud\Storage\StorageClient;
use GuzzleHttp\Client;

$storage = new StorageClient;

$bucket = $storage->bucket('my-bucket');
$obj = $bucket->object('foo-bar.png');

// This URI is ready to accept an HTTP PUT request.
$uri = $obj->signedUrl(time()+3600, [
    'method' => 'PUT',
    'contentType' => 'image/png'
]);

// This part would be managed by the XMLHttpRequest on the client.
$client = new Client;
$content = file_get_contents('/path/to/test.png');
$client->put($uri, [
    'body' => $content,
    'headers' => [
        'Content-Type' => ['image/png']
    ]
]);

// This just proves that the content uploaded as expected.
$remoteContent = $obj->downloadAsString();
assert($content === $remoteContent);

Confirmed, thank you for your prompt and detailed response.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Google-K picture Google-K  路  6Comments

mjniuz picture mjniuz  路  6Comments

lorenzosfarra picture lorenzosfarra  路  7Comments

ammopt picture ammopt  路  6Comments

LoekvanKooten picture LoekvanKooten  路  6Comments