0

使用带有 base64 数据的 PUT 请求上传到 Google 云存储时,图像 (PNG) 不会显示在浏览器中,并说它包含错误(在 FF 中查看时)。

在文本编辑器中打开图像文件后,我可以看到 base64 数据“data:image/png;base64,iVBORw ...”,因此它不会转换为二进制。

我是要上传二进制文件还是有办法让它在 HTTP 正文中与 base64 一起使用?

基本代码示例。

    <?php

    $theDate = 日期(DATE_RFC822);
    $emailID = "*******.gserviceaccount.com";
    $priv_key = file_get_contents("*******-privatekey.p12");

    函数签名URL($文件名,$bucket,$method = 'PUT'){
      全局 $emailID;
      全局 $priv_key;

       $签名=“”;
       $持续时间 = 60;
       $certs = 数组();
          if (!openssl_pkcs12_read($priv_key, $certs, 'notasecret')) { echo "无法解析 p12 文件。OpenSSL 错误:" 。openssl_error_string(); 出口(); }

        $expires = time() + $duration;
        $to_sign = ( $method . "\n\nimage/png; charset=UTF-8\n" . $expires . "\nx-goog-acl:public-read\n" . "/" . $bucket . " /" . $文件名);
        $RSAPrivateKey = openssl_pkey_get_private($certs["pkey"]);

      if (!openssl_sign($to_sign, $signature, $RSAPrivateKey, 'sha256'))
      {
        error_log('openssl_sign 失败!');
        $signature = '失败';
      } 别的 {
        $signature = urlencode(base64_encode($signature));
      }

      return ('http://' . $bucket . '/' . $filename . '?GoogleAccessId=' . $emailID . '&Expires=' . $expires . '&Signature=' . $signature);
        openssl_free_key($RSAPrivateKey);
    }

    $UploadURL = signedURL('test.png', 'mybucket.mydomain.net', 'PUT');

    //回显 $UploadURL;

    ?>

    <脚本>
    var base64img = "data:image/png;base64,iVB...";//截图
    var xhr = new XMLHttpRequest();

    xhr.open("PUT", "<?php echo $UploadURL ?>");
    xhr.setRequestHeader("内容类型", "图片/png");
    xhr.setRequestHeader("x-goog-acl", "public-read"); //尝试对文件设置公共读取
    xhr.setRequestHeader("内容长度", base64img.length); // Chrome 抛出错误
    xhr.send(base64img);
    </脚本>

根据我在网上阅读的内容,我觉得这是可能的,但我找不到任何示例准确显示 PUT 的完成方式,以表明缺少什么使其工作。

4

1 回答 1

0

You typically want to avoid using base64 encoding unless you really need it. Encoding something in base64 incurs a size overhead, and also requires decoding before it can be used, which is effectively a CPU overhead. Essentially, you only want b64 encode something if the protocol and transport you're using can't handle binary data.

So, in your case I think the answer is to avoid base64 and just upload raw bytes. In the general case, if you do base64 encode something before storing it in Cloud Storage, you'll need to plan for a decode step in whatever software is pulling it back out.

于 2013-06-14T17:31:26.863 回答