Cors 使用JavaScript和restapi从googlephotos下载图像blob

Cors 使用JavaScript和restapi从googlephotos下载图像blob,cors,blob,google-photos,Cors,Blob,Google Photos,我无法使用Google Photos REST API在JavaScript客户端中下载图像块。我的XMLHttpRequest得到了404。我有一个有效的OAuth令牌,可以列出mediaItems。令牌是使用脱机访问代码生成的。同样的XMLHttpRequest下载方法适用于GDrive和Dropbox,允许我显示下载进度 我尝试使用“=d”和“=w123h345-c”baseUrl后缀(其中123和345分别是图像的宽度和高度)。我已经尝试将fetch和XMLHttpRequest与各种认

我无法使用Google Photos REST API在JavaScript客户端中下载图像块。我的XMLHttpRequest得到了404。我有一个有效的OAuth令牌,可以列出mediaItems。令牌是使用脱机访问代码生成的。同样的XMLHttpRequest下载方法适用于GDrive和Dropbox,允许我显示下载进度

我尝试使用“=d”和“=w123h345-c”baseUrl后缀(其中123和345分别是图像的宽度和高度)。我已经尝试将fetch和XMLHttpRequest与各种认证访问组合使用(例如,将access_令牌用作URL参数或在授权标头中)

请注意,相同的URL在Chrome URL栏中工作正常,可以下载文件,也可以显示完整的res版本。我还可以使用curl从命令行下载文件,URL作为参数传递访问令牌。如果使用选项设置发送curl命令,我在响应中无法获得访问控制允许来源:

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>"

谷歌照片端点似乎不支持CORS访问像素数据

同样,可以使用curl或标记来显示像素。在添加CORS访问之前,您无法在客户端JS中获取数据

< 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"
< 
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)
})