Google云端存储签名URL上传+ Dropzone.js

时间:2018-03-21 04:50:12

标签: google-cloud-platform google-cloud-storage dropzone.js

我正在尝试使用Dropzone.js使用签名网址直接上传到Google云端存储。我已设法覆盖添加到Dropzone的每个文件的上传URL。 Chrome开发工具表示正在发出PUT请求,但我不可避免地收到HTTP 400错误。

这是我的Dropzone.js配置

Dropzone.options.myAwesomeDropzone = {
    url: '/',
    uploadMultiple: false,
    method: 'PUT',
    parallelUploads: 1,
    uploadMultiple: false,
    header: '',
    autoProcessQueue: false,
    autoDiscover: false,
    maxFiles: 1,
    acceptedFiles: 'image/*,video/*',
    accept: function(file, done) {
        var self = this;
        $.post('/api/v1/signed_file_upload', {key: window.apiKey, name: file.name, type: file.type}, function(data) {
            if(data.success) {
                file.uploadURL = data.data;
                done()
                setTimeout(function() {
                    self.processFile(file)
                }, 0)
            } else {
                done(data.message)
            }
        })
    },
    init: function() {
        var self = this;
        this.on('processing', function(file) {
            self.options.url = file.uploadURL
        })

        this.on('sending', function(file, xhr, formData) {
            var _send = xhr.send
            xhr.send = function() {
                _send.call(xhr, file)
            }
        });

    }
};

我的签名网址具有以下结构:

https://www.googleapis.com/upload/storage/v1/b/{bucket_name}/o/{object_name}.png?GoogleAccessId=xxx@xxx.iam.gserviceaccount.com&Expires=1521610072&Signature=xxx

Chrome开发者工具会针对上传请求显示此信息:

enter image description here

我不可避免地收到HTTP 400响应。有时身体是空的,有时它会返回一个JSON对象,说

{
    "error": {
        "errors": [
            {
                "domain": "global",
                "reason": "badContent",
                "message": "Unsupported content with type: image/jpeg"
            }
        ],
        "code": 400,
        "message": "Unsupported content with type: image/jpeg"
    }
}

我的签名生成功能是

function storage_url($file_name, $bucket_name = '', $content_type = '', $method = 'PUT', $duration = 3000) { 
    $expires      = time() + $duration; 
    $signature    = '';
    $to_sign      = ($method . "\n\n" . $content_type . "\n" . $expires . "\n" . '/' . $bucket_name . '/' . $file_name); 
    $private_key  = json_decode(file_get_contents('xxx.json'))->private_key;

    if(!openssl_sign( $to_sign, $signature, $private_key, 'sha256' )) 
    { 
        return false;
    } 
    else 
    { 
        $signature = urlencode(base64_encode($signature)); 
    }

    error_log($to_sign);

    return 'https://www.googleapis.com/upload/storage/v1/b/' . $bucket_name . '/o/' . urlencode($file_name) . 
        '?GoogleAccessId=' . 'xxx@xxx.iam.gserviceaccount.com' . 
        '&Expires=' . $expires . 
        '&Signature=' . $signature;
}

1 个答案:

答案 0 :(得分:1)

GCS有两个API。第一个是XML API,它使用storage.googleapis.com之类的域。第二个是JSON API,它使用www.googleapis.com等域名。

您正在使用JSON API,这很好,但不幸的是它不支持签名的网址。使用XML API的格式制作上传网址:https://cloud.google.com/storage/docs/xml-api/put-object-upload