使用 JavaScript 和 REST API 从 Google Photos 下载图像 blob

问题描述 投票:0回答:2

我无法使用 Google Photos REST API 在 JavaScript 客户端中下载图像 blob。我的 XMLHttpRequest 收到 404。我有一个有效的 OAuth 令牌,可以列出媒体项目。该令牌是使用离线访问代码生成的。相同的 XMLHttpRequest 下载方法适用于 GDrive 和 Dropbox,允许我显示下载进度。

我尝试使用“=d”和“=w123h345-c”baseUrl 后缀(其中 123 和 345 分别是图像的宽度和高度)。我尝试过将 fetch 和 XMLHttpRequest 与凭据访问的各种组合一起使用(例如,使用 access_token 作为 URL 参数或在授权标头中使用。

请注意,相同的 URL 在 Chrome URL 栏中可以正常工作,无论是下载文件还是显示完整版本。我还可以使用curl 从命令行下载文件,并将URL 作为参数传递access_token。如果我使用选项设置发送curl命令,我不会在响应中得到Access-Control-Allow-Origin:

curl --verbose --output foo -H "Origin: http://localhost:3000" \
-H "Access-Control-Request-Method: GET" \
-H "Access-Control-Request-Headers: X-Requested-With" \
-X OPTIONS \
"https://lh3.googleusercontent.com/lr/<baseUrl>=d?access_token=<access_token>"

返回以下响应标头:

< HTTP/2 200 
< access-control-expose-headers: Content-Length
< etag: "v3d"
< expires: Fri, 01 Jan 1990 00:00:00 GMT
< cache-control: private, max-age=86400, no-transform
< content-disposition: attachment;filename="MA-Distancing.png"
< content-type: image/png
< vary: Origin
< x-content-type-options: nosniff
< date: Thu, 06 Aug 2020 20:06:22 GMT
< server: fife
< content-length: 772787
< x-xss-protection: 0
< alt-svc: h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
< 

我发现了一个类似的问题,但没有答案。

我的所有测试都在 localhost:3000 上进行,因为我还没有对 photoslibrary.readonly 范围进行 OAuth 验证。正如预期的那样,我在测试期间收到“高级”身份验证弹出窗口,并且 access_token 有效并且可用于列出和获取媒体项目,但不能用于媒体下载。

export const xhrDownloadURL = (url, accessToken, body, onProgress) => new Promise((resolve, reject) => {
  const xhr = new XMLHttpRequest()
  xhr.open('GET', url)
  if (accessToken) xhr.setRequestHeader('Authorization', `Bearer ${accessToken}`)
  xhr.setRequestHeader('Access-Control-Allow-Credentials', true)
  xhr.responseType = 'blob'
  const updateProgress = e => {
    if (onProgress) {
      const { loaded, total } = e
      const cancel = onProgress({ loaded, size: total })
      if (cancel.type === CACHE_CANCELED) {
        reject(new Error(`onProgress canceled download at range ${loaded} of ${total} in ${url}`))
      }
    }
  }
  xhr.onloadstart = updateProgress
  xhr.onprogress = updateProgress
  xhr.onabort = event => {
    console.warn(`xhr ${url}: download aborted at ${event.loaded} of ${event.total}`)
    reject(new Error('Download aborted'))
  }
  xhr.onerror = event => {
    console.error(`xhr ${url}: download error at ${event.loaded} of ${event.total}`)
    reject(new Error('Error downloading file'))
  }
  xhr.onload = event => {
    const { loaded, total } = event
    if (onProgress) onProgress({ loaded, size: total })
    const data = process.env.NODE_ENV === 'test' && Array.isArray(xhr.response) && xhr.response.length === 1 ? xhr.response[0] : xhr.response
    resolve(data)
  }
  xhr.onloadend = (/* event */) => {
    // console.log(`xhr ${url}: download of ${event.total} completed`)
  }
  xhr.ontimeout = event => {
    console.warn(`xhr ${url}: download timeout after ${event.loaded} of ${event.total}`)
    reject(new Error('Timout downloading file'))
  }
  xhr.send(body)
})
cors blob google-photos
2个回答
1
投票

Google Photos 端点似乎不支持 CORS 访问像素数据。

https://issuetracker.google.com/issues/118662029

再次强调,可以使用curl 或 标签来显示像素。在添加 CORS 访问之前,您只是无法在客户端 JS 中获取数据。


0
投票

基本 URL 参数的 Google 文档

如果您将

=d

 参数添加到图像基本 URL 的末尾,则 Google 支持照片下载。  如果您通过 
有效的
baseUrl
查询获取图像详细信息,您将找到
mediaItems

请查看本文档中的表格。 如果您将下载参数 (=d) 附加到 Google Photos 图片的基本 URL 的末尾,它应该能够满足您的要求。

希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.