【问题标题】:Uploading photo to Google Photos API not returning upload token将照片上传到 Google Photos API 不返回上传令牌
【发布时间】:2018-08-05 11:39:23
【问题描述】:

我正在使用 2018 版 Google Photos API 上传图片和媒体,如下所述:“Uploading Bytes”

当我上传 新 图片或视频时,我从未在响应正文中获得上传令牌。它始终是一个空的正文,根据上面的链接,这意味着字节已经上传(但这是一个新的上传)。

这是一个请求/响应示例:

request: 
    POST https://photoslibrary.googleapis.com/v1/uploads
request headers: 
    authorization: Bearer abcd1234
    X-Goog-Upload-Protocol: raw
    X-Goog-Upload-File-Name: 20140317T082917_001.jpg
    content-type: application/octet-stream
    content-length: 1292868
    accept: application/json
-----------------------------------------------------
response: OK [200]
response headers:
    Alt-Svc: [quic=":443"; ma=2592000; v="44,43,39,35"]
    Server: [UploadServer]
    X-GUploader-UploadID: [AEnB2UqT6y8KyZNCPyAaFeCj7I_ABIlwLJQMpltYzQ7D8blW4v3uKSlMT7dbNjFV0i_7ApzoR-i26ZtZ9kHkB7bI8n8ojgOnNA]
    Content-Length: [510]
    Date: [Sun, 05 Aug 2018 11:19:15 GMT]
    Content-Type: [text/plain]
response body:
    null

我也尝试使用 X-GUploader-UploadID 标头中返回的值,但这会导致 500 错误。

有人可以提供一个如何将字节上传到 Google Photos API 的工作示例吗?

谢谢!

【问题讨论】:

    标签: java http google-photos google-photos-api


    【解决方案1】:

    我认为您只是没有查看响应内容。以下适用于 Python,当然您也可以使其适用于 Java:

    def upload_files(self, filepath, album_id):
        filename = os.path.basename(filepath)
        url = 'https://photoslibrary.googleapis.com/v1/uploads'
        authorization = 'Bearer ' + creds.access_token
    
        headers = {
            "Authorization": authorization,
            'Content-type': 'application/octet-stream',
            'X-Goog-Upload-File-Name': filename,
            'X-Goog-Upload-Protocol': 'raw',
        }
        with open(filepath, "rb") as image_file:
            response = requests.post(url, headers=headers, data=image_file)
            assert response.status_code == 200
            token = response.text  # !!!
        return service.mediaItems().batchCreate(body=dict(
            albumId=album_id,
            newMediaItems=[
                {"simpleMediaItem": {"uploadToken": token}}]
        )).execute()
    

    【讨论】:

    • 知道如何使用 react-native 进行这项工作吗?我有一个 base64 编码的图像,photoslibrary.googleapis... 返回一个 uploadToken,当我使用它将图像上传到相册时,我收到“NOT_IMAGE:尝试创建此媒体项目时出错。”跨度>
    • @mbunch 您是否尝试过使用非 base64 编码的图像?
    • @David 我不记得我的最终解决方案,但就像你建议的那样,我找到了一种方法来获取 google photos api 所需的二进制数据。
    【解决方案2】:

    您实际上确实得到了响应正文。如果你看看你的回复

    response: OK [200]
    response headers:
        Alt-Svc: [quic=":443"; ma=2592000; v="44,43,39,35"]
        Server: [UploadServer]
        X-GUploader-UploadID: [AEnB2UqT6y8KyZNCPyAaFeCj7I_ABIlwLJQMpltYzQ7D8blW4v3uKSlMT7dbNjFV0i_7ApzoR-i26ZtZ9kHkB7bI8n8ojgOnNA]
        Content-Length: [510]
        Date: [Sun, 05 Aug 2018 11:19:15 GMT]
        Content-Type: [text/plain]
    response body:
        null
    

    Content-Length 字段表示正文的字节长度,在您的情况下为 510。您使用哪种方法获取此信息?你目前的实现是什么?

    如果您只是尝试执行请求,例如通过curl 然后我实际上不知道,为什么没有响应主体,但是无论如何它都不适合 java 标记的范围,所以我假设您自己在一些自写的 java 中解析了响应代码?

    因为你没有提供它,这只是猜测,但我假设你在解析响应时错过了一些东西。

    【讨论】:

    • 上传需要response body吗?
    【解决方案3】:

    这对我有用,以下方法中返回的 r.content 包含上传令牌,您需要将其传递给 MediaItems:batchCreate API 调用,以便在用户的库中创建媒体:

    def upload(your_access_token, your_media_path):
    item = open(your_media_path, 'rb').read()
    url = 'https://photoslibrary.googleapis.com/v1/uploads'
    headers = {
        'Authorization': 'Bearer ' + token,
        'Content-Type': 'application/octet-stream',
        'X-Goog-Upload-File-Name': 'image1.jpg',
        'X-Goog-Upload-Protocol': 'raw',
    }
    
    r = requests.post(url, data = item, headers = headers)
    return r.content.decode('utf-8')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-16
      • 1970-01-01
      • 1970-01-01
      • 2012-08-19
      • 1970-01-01
      • 2018-10-14
      相关资源
      最近更新 更多