如何从GooglePicker上的选定文件中获取Blob [英] How to get a blob from selected files on GooglePicker

查看:66
本文介绍了如何从GooglePicker上的选定文件中获取Blob的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将GooglePicker与React一起使用,得到的结果是一系列对象...

I am using GooglePicker with React, and the result I am getting is an array of objects...

[
  {
    "id": "1...m",
    "serviceId": "docs",
    "mimeType": "image/jpeg",
    "name": "name.jpg",
    "description": "",
    "type": "photo",
    "lastEditedUtc": 1575388407136,
    "iconUrl": "https://drive-thirdparty.googleusercontent.com/16/type/image/jpeg",
    "url": "https://drive.google.com/file/d/1...m/view?usp=drive_web",
    "embedUrl": "https://drive.google.com/file/d/1...m/preview?usp=drive_web",
    "sizeBytes": 111364,
    "rotation": 0,
    "rotationDegree": 0,
    "parentId": "0...A"
}]

因此,我尝试使用

const fetchOptions = {标头:{授权:`Bearer $ {accessToken}`}};

docs.forEach((file) => {
  ...
  fetch(file.url, fetchOptions).then((res) => {
    const blob = res.blob();
    uploadFile(blob);
  });
});

但是我得到 403 CORS ;我尝试在选择器中设置 relayUrl ,但这破坏了选择器.

But I get 403 or CORS; I tried setting the relayUrl in the picker, but this broke the Picker.

注意:

  1. 我的auth2中有以下3个作用域:
  1. I have these 3 scopes in my auth2:
    ['https://www.googleapis.com/auth/drive.file',
    'https://www.googleapis.com/auth/drive',
    'https://www.googleapis.com/auth/drive.readonly']```

  • 我将计算机的URL和端口和协议设置为授权JavaScript起源"和授权重定向URI"
  • 有什么想法吗?

    我也尝试过使用Google API,如下所示:

    I also tried using Google API like this:

    const FILE_URL = 'https://www.googleapis.com/drive/v3/files';
    const url = isDoc
            ? `${FILE_URL}/${file.id}/export?mimeType=${mimeType}`
            : `${FILE_URL}/${file.id}?alt=media`;
    
          fetch(url, fetchOptions).then((res) => {
            const blob = res.blob();
            uploadFile(blob);
          });
    
    

    推荐答案

    您将需要Drive API

    从您的问题看来,您似乎正在尝试使用Google Picker进行所有操作.但是,选择器只会为您提供文件的有限元数据,因此您可以使用您的帐户打开它们(即在另一个窗口中查看它们)或上传文件.如果您要下载实际文件,则需要使用Drive API.

    You'll need the Drive API

    From your question it seems that you are trying to do everything with Google Picker. However, the picker will only get you limited metadata for the files, so you can open them with your account (i.e. see them in another window) or let you upload files. If you want to download the actual file, then you will need to use the Drive API.

    浏览器JavaScript的驱动器快速入门

    流可能是:

    • 让用户选择文件
    • 获取元数据对象
    • 从对象中提取文件ID
    • 调用Drive API( get alt ='media')

    如果我误解了并且您已经在使用Drive API,那么查看与此相关的代码将很有帮助.

    If I have misunderstood and you are already using the Drive API, then it would be helpful to see the associated code with that.

    下面是一个示例,该示例使用Picker API通过同一登录客户端通过 gapi 将其供入Drive API.

    Here is an example of using the Picker API to feed into the Drive API with gapi using the same login client.

    HTML

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta charset="utf-8" />
        <title>Google Picker Example</title>
        
      </head>
      <body>
        <button id="authorize_button" style="display: none;">Authorize</button>
        <button id="signout_button" style="display: none;">Sign Out</button>
        <div id="result"></div>
    
        <script type="text/javascript" src="script.js"></script>
        <script async defer src="https://apis.google.com/js/api.js"
        onload="this.onload=function(){};handleClientLoad()"
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
      </script>
      </body>
    </html>
    

    JS

    const API_KEY = 'AI...';
    const CLIENT_ID = '44...';
    const appId = "44...";
    
    const SCOPES = ["https://www.googleapis.com/auth/drive"];
    
    const DISCOVERY_DOCS = [
      "https://www.googleapis.com/discovery/v1/apis/drive/v3/rest",
    ];
    
    const authorizeButton = document.getElementById("authorize_button");
    const signoutButton = document.getElementById("signout_button");
    
    // Use the Google API Loader script to load the google.picker script.
    function handleClientLoad() {
      gapi.load("client:auth2:picker", initClient);
    }
    
    function initClient() {
      gapi.client.init({
          apiKey: API_KEY,
          clientId: CLIENT_ID,
          discoveryDocs: DISCOVERY_DOCS,
          scope: SCOPES[0]
        })
        .then(
          function () {
            // Listen for sign-in state changes.
            gapi.auth2.getAuthInstance().isSignedIn.listen(handleSignIn);
    
            // Handle the initial sign-in state.
            handleSignIn(gapi.auth2.getAuthInstance().isSignedIn.get());
            authorizeButton.onclick = handleAuthClick;
            signoutButton.onclick = handleSignoutClick;
          },
          function (error) {
            appendPre(JSON.stringify(error, null, 2));
          }
        );
    }
    
    function handleSignIn(isSignedIn) {
      if (isSignedIn) {
        authorizeButton.style.display = "none";
        signoutButton.style.display = "block";
        createPicker();
      } else {
        authorizeButton.style.display = "block";
        signoutButton.style.display = "none";
      }
    }
    
    function handleAuthClick(event) {
      gapi.auth2.getAuthInstance().signIn();
    }
    
    function handleSignoutClick(event) {
      gapi.auth2.getAuthInstance().signOut();
    }
    
    function createPicker() {
      const token = gapi.client.getToken().access_token
      if (token) {
        
        let view = new google.picker.View(google.picker.ViewId.DOCS);
        view.setMimeTypes("image/png,image/jpeg,image/jpg");
        let picker = new google.picker.PickerBuilder()
          .enableFeature(google.picker.Feature.NAV_HIDDEN)
          .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
          .setAppId(appId)
          .setOAuthToken(token)
          .addView(view)
          .addView(new google.picker.DocsUploadView())
          .setDeveloperKey(API_KEY)
          .setCallback(getFile)
          .build();
        picker.setVisible(true);
      }
    }
    
    function getFile(pickerResp) {
      gapi.client.drive.files
        .get({
          fileId: pickerResp.docs[0].id,
          alt: 'media'
        })
        .then(resp => {
          console.log("fetch response", resp.status)
          let binary = resp.body
          // EDIT - addition from Gabrielle vvvv
          let l = binary.length
          let array = new Uint8Array(l);
          for (var i = 0; i<l; i++){
            array[i] = binary,charCodeAt(i);
          }
          let blob = new Blob([array], {type: 'application/octet-stream'});
          // EDIT - addition from Gabrielle ^^^^
    }
    

    此代码改编自驱动器快速入门选择器快速入门.

    注意-这的确在控制台中给出了一个错误,但它的工作原理似乎相同.这似乎是Picker的错误- https://issuetracker.google.com/177046274

    Note - this does give an error in the console, but it does seem to work all the same. This does seem to be a bug with the Picker - https://issuetracker.google.com/177046274

    Gabrielle的编辑
    注意-将get与 alt = media 一起使用适用于二进制文件.要获取工作表/文档/幻灯片等,您需要使用 export 端点.

    EDIT from Gabrielle
    Note - using get with alt = media is for binary files. To get sheets/docs/slides etc, you need to use the export end point.

    这篇关于如何从GooglePicker上的选定文件中获取Blob的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆