【问题标题】:Problem Posting Images To Google Drive API V3将图像发布到 Google Drive API V3 时出现问题
【发布时间】:2019-12-24 22:33:03
【问题描述】:

我在将图片发布到 https://www.googleapis.com/upload/drive/v3/files?uploadType=media 时遇到问题。该文件是在我的 Google Drive 上创建的,但 jpeg 的大小始终为 35KB,因此似乎没有任何图像内容被上传。

最初我认为这是vue-google-api 中的错误,但现在怀疑这是 Google Drive API V3 的问题。当我尝试将图像直接发布到 API 时,我遇到了同样的问题。

请求

POST https://www.googleapis.com/upload/drive/v3/files?uploadType=media
Accept: */*
Accept-Encoding: gzip, deflate
Content-Type: image/jpeg
Content-Length: 26837
Accept-Language: en-ca
Authorization: Bearer ya29.Gl1pB5BN9khs33ygA9pnIbyxJYp87teqDUfm55EsEHmmPJz0...

/9j/4AAQSkZJRgABAQEASABIAAD//gAMQXBwbGVNYXJrCv/bAIQABwUFBgUFBwYGBggHBwgKEQs...

回应

HTTP/1.1 200 OK

Server: UploadServer
Content-Type: application/json; charset=UTF-8
X-GUploader-UploadID: AEnB2UrjBAKhEMI-rCdzXpfAF3rM3oBABNUVH9AnhFtoXsoRroYV3By4rVqEuU1mn_5rJ2u_msN99Z1m2r-6Lh53fAowxmQ7QGAgWr2bP6cEwfnfV9JE-Vc
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Vary: Origin, X-Origin
Date: Mon, 19 Aug 2019 17:04:18 GMT
Alt-Svc: quic=":443"; ma=2592000; v="46,43,39"
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 118
{
    "kind": "drive#file",
    "id": "16dC3Fv2vKIur426INggTZ6GzDvyRUPrV",
    "name": "Untitled",
    "mimeType": "image/jpeg"
}

有没有人成功上传图片到Google Drive API V3?知道可能出了什么问题吗?

【问题讨论】:

  • "Content-Length: 26837" 这是正确的 jpeg 大小吗?试试base64编码吧。
  • 我正在使用capacitor.ionicframework.com/docs/apis/camera 并将图像作为base64 字符串取回,然后使用parseInt(base64.replace(/=/g,"").length * 0.75) 计算Content-Length。这看起来正确吗?
  • 如果你说你上传的字符串已经是base64编码的,那么content-length应该只是长度,你应该添加一个content-transfer-encoding头。

标签: google-drive-api


【解决方案1】:

在拉了几个小时的头发并查看了相同的答案之后。唯一对我有用的是从多部分请求(Google 文档)更改为使用 FormData。

感谢answer。

const metadata = JSON.stringify({
  name: myFile.name,
  mimeType: myFile.type,
});

const requestData = new FormData();

requestData.append("metadata", new Blob([metadata], {
  type: "application/json"
}));

requestData.append("file", items[0].file);

const xhr = new XMLHttpRequest();

xhr.open("POST", "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart");

const token = gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token;

xhr.setRequestHeader("Authorization", `Bearer ${token}`);

xhr.send(requestData);

【讨论】:

    【解决方案2】:

    这个修改怎么样?关于uploadType=media,无法包含元数据,也找不到base64数据上传转换的方法。当我在您的问题中看到the link 时,我注意到您尝试了两种方法。一个是uploadType=media。另一个是uploadType=multipart。在链接中,我还确认这两个脚本都不起作用。

    uploadType=multipart可以上传base64数据并转换成二进制数据。所以在这里,我想对uploadType=multipart提出修改意见。

    修改点:

    我认为您的请求正文几乎是正确的。但需要稍作修改。

    • 在您的问题中,您说数据转换为base64。在这种情况下,需要将Content-Transfer-Encoding 设置为请求正文。
    • 文件上传到Google Drive时,即使没有设置Content-Length,也可以上传文件。

    修改脚本:

    请修改contentDisposition()如下。

    从:
    body += "--" + boundary
         + "\r\nContent-Disposition: form-data; name=" + key
         + "\r\nContent-type: " + formData[key].type
         + "\r\n\r\n" + formData[key].value + "\r\n";
    
    到:
    body += "--" + boundary
         + "\r\nContent-Disposition: form-data; name=" + key
         + "\r\nContent-type: " + formData[key].type
         + (key == "file" ? "\r\nContent-Transfer-Encoding: base64" : "")  // Added
         + "\r\n\r\n" + formData[key].value + "\r\n";
    

    另外,请将uploadGoogleMultipart()修改如下。

    从:
    headers: {
        "Content-Type": "multipart/related; boundary=" + boundary,
        'Content-Length': body.length
    },
    
    到:
    headers: {
        "Content-Type": "multipart/related; boundary=" + boundary,
    },
    

    注意:

    • 在此修改中,假设您已经能够使用 Drive API 将文件上传到 Google Drive。

    参考:

    如果我误解了您的问题并且这不是您想要的方向,我深表歉意。

    【讨论】:

    • @Dale Zak 感谢您的回复和测试。我很高兴你的问题得到了解决。也谢谢你。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    • 2020-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多