美文网首页
Google Development Api功能开发使用示例

Google Development Api功能开发使用示例

作者: 说叁两事 | 来源:发表于2022-12-22 17:17 被阅读0次

    Sample1:授权

    概述

    主要分为五步:

    1. 加载api工具库

    2. 登陆

    3. scopes授权

    4. 加载对应的工具文档

      • 工具文档决定了调用gapi.client.*对象下的哪一个服务
    5. 根据工具文档中的resources字段调用方法

    加载gapi工具库

    gapi === google application interface

      <script src="https://apis.google.com/js/api.js"></script>
    

    该工具库会全局注册gapi对象。

    Notes: gapi的文档<<u>https://github.com/google/google-api-javascript-client/blob/master/docs/reference.md</u>>

    加载授权模块

      gapi.load("client:auth2", function() {
        gapi.auth2.init({
          client_id: CLIENTID,
          // cookiepolicy: 'single_host_origin',
          plugin_name: 'hello' // 必填,可以是任意值 —— 不填,会报错 {error: "popup_closed_by_user"}
        });
      });
    

    登陆且授权

      <button onclick="authenticate().then(loadClient)">authorize and load</button>
    

    点击按钮后,授权服务,加载需要的服务API文档(gapi根据加载的文档会动态生成对应的服务方法)。

      const scopes = [
        "https://www.googleapis.com/auth/drive",
        "https://www.googleapis.com/auth/drive.appdata",
        "https://www.googleapis.com/auth/drive.file",
        "https://www.googleapis.com/auth/drive.metadata",
        "https://www.googleapis.com/auth/drive.metadata.readonly",
        "https://www.googleapis.com/auth/drive.photos.readonly",
        "https://www.googleapis.com/auth/drive.readonly"
      ] // 用户授权可访问的服务列表
      function authenticate() {
        return gapi.auth2.getAuthInstance()
          .signIn({
            scope: scopes.join(" ")
          })
          .then(
            function() {
              console.log("Sign-in successful");
            },
            function(err) {
              console.error("Error signing in", err);
            }
          );
      }
      function loadClient() {
        // 有了授权操作,就不需要设置ApiKey了,二者冲突<https://stackoverflow.com/questions/17436940/google-simple-api-key-stopped-working>
        /**
          * 以当前用户身份调取Api —— 使用access_token
          * 以开发者身份调用API —— 使用API key
        */
        // gapi.client.setApiKey(CLIENTSECRET);
        return gapi.client.load("https://content.googleapis.com/discovery/v1/apis/drive/v3/rest")
          .then(
            function() {
              console.log("GAPI client loaded for API");
            },
            function(err) {
              console.error("Error loading GAPI client for API", err);
            }
          );
      }
    

    调用方法

     <button onclick="execute()">execute</button>
    

    直接浏览器打开https://content.googleapis.com/discovery/v1/apis/drive/v3/rest,查找对应的resources字段,调用对应的methods即可。

      function execute() {
        return gapi.client.drive.files.list({})
          .then(
            function(response) {
              // Handle the results here (response.result has the parsed body).
              console.log("Response", response);
            },
            function(err) {
              console.error("Execute error", err);
            }
          );
      }
    

    完整代码

    <!DOCTYPE html>
    <html>
      <head>
        <title>Drive API Quickstart</title>
        <meta charset="utf-8" />
      </head>
      <body>
        <p>Drive API Quickstart</p>
    
        <!--Add buttons to initiate auth sequence and sign out-->
        <button onclick="authenticate().then(loadClient)">authorize and load</button>
        <button onclick="execute()">execute</button>
    
        <pre id="content" style="white-space: pre-wrap;"></pre>
    
        <script src="https://apis.google.com/js/api.js"></script>
        <script type="text/javascript">
          const CLIENTID = '<your client_id>'
          const CLIENTSECRET = '<your client_secret>'
          const scopes = [
            "https://www.googleapis.com/auth/drive",
            "https://www.googleapis.com/auth/drive.appdata",
            "https://www.googleapis.com/auth/drive.file",
            "https://www.googleapis.com/auth/drive.metadata",
            "https://www.googleapis.com/auth/drive.metadata.readonly",
            "https://www.googleapis.com/auth/drive.photos.readonly",
            "https://www.googleapis.com/auth/drive.readonly"
          ] // 用户授权可访问的服务列表
          function authenticate() {
            return gapi.auth2.getAuthInstance()
              .signIn({
                scope: scopes.join(" ")
              })
              .then(
                function() {
                  console.log("Sign-in successful");
                },
                function(err) {
                  console.error("Error signing in", err);
                }
              );
          }
          function loadClient() {
            // 有了授权操作,就不需要设置ApiKey了,二者冲突<https://stackoverflow.com/questions/17436940/google-simple-api-key-stopped-working>
            /**
             * 以当前用户身份调取Api —— 使用access_token
             * 以开发者身份调用API —— 使用API key
            */
            // gapi.client.setApiKey(CLIENTSECRET);
            return gapi.client.load("https://content.googleapis.com/discovery/v1/apis/drive/v3/rest")
              .then(
                function() {
                  console.log("GAPI client loaded for API");
                },
                function(err) {
                  console.error("Error loading GAPI client for API", err);
                }
              );
          }
      // Make sure the client is loaded and sign-in is complete before calling this method.
          function execute() {
            return gapi.client.drive.files.list({})
              .then(
                function(response) {
                  // Handle the results here (response.result has the parsed body).
                  console.log("Response", response);
                },
                function(err) {
                  console.error("Execute error", err);
                }
              );
          }
          gapi.load("client:auth2", function() {
            gapi.auth2.init({
              client_id: CLIENTID,
              // cookiepolicy: 'single_host_origin',
              plugin_name: 'hello' // 必填,可以是任意值 —— 不填,会报错 {error: "popup_closed_by_user"}
            });
          });
        </script>
      </body>
    </html>
    

    Sample2:获取access_token

    相关资源

       <script async defer src="https://apis.google.com/js/api.js" onload="gapiLoaded()"></script>
      <script async defer src="https://accounts.google.com/gsi/client" onload="gisLoaded()"></script>
    

    获取用户实例

      tokenClient = google.accounts.oauth2.initTokenClient({
        client_id: CLIENT_ID,
        scope: SCOPES,
        callback: '', // defined later
      });
    

    账号登陆检测

      if (gapi.client.getToken() === null) {
        // Prompt the user to select a Google Account and ask for consent to share their data
        // when establishing a new session.
        tokenClient.requestAccessToken({prompt: 'consent'});
      } else {
        // Skip display of account chooser and consent dialog for an existing session.
        tokenClient.requestAccessToken({prompt: ''});
      }
    

    登陆后的回调

      tokenClient.callback = async (resp) => {
        if (resp.error !== undefined) {
          throw (resp);
        }
        document.getElementById('signout_button').style.visibility = 'visible';
        document.getElementById('authorize_button').innerText = 'Refresh';
        await listFiles();
      };
    

    退出账号

      const token = gapi.client.getToken();
      if (token !== null) {
        google.accounts.oauth2.revoke(token.access_token);
        gapi.client.setToken('');
      }
    

    全部代码

    <!DOCTYPE html>
    <html>
      <head>
        <title>Drive API Quickstart</title>
        <meta charset="utf-8" />
      </head>
      <body>
        <p>Drive API Quickstart</p>
    
        <!--Add buttons to initiate auth sequence and sign out-->
        <button id="authorize_button" onclick="handleAuthClick()">Authorize</button>
        <button id="signout_button" onclick="handleSignoutClick()">Sign Out</button>
    
        <pre id="content" style="white-space: pre-wrap;"></pre>
    
        <script type="text/javascript">
          const CLIENT_ID = '<your-client_id>';
          const API_KEY = '<your-api_key>';
    
          const DISCOVERY_DOC = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';
          const SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    
          let tokenClient;
          let gapiInited = false;
          let gisInited = false;
    
          document.getElementById('authorize_button').style.visibility = 'hidden';
          document.getElementById('signout_button').style.visibility = 'hidden';
    
          function gapiLoaded() {
            gapi.load('client', initializeGapiClient);
          }
    
          async function initializeGapiClient() {
            await gapi.client.init({
              discoveryDocs: [DISCOVERY_DOC],
            });
            gapiInited = true;
            maybeEnableButtons();
          }
          function gisLoaded() {
            tokenClient = google.accounts.oauth2.initTokenClient({
              client_id: CLIENT_ID,
              scope: SCOPES,
              callback: '', // defined later
            });
            gisInited = true;
            maybeEnableButtons();
          }
    
          function maybeEnableButtons() {
            if (gapiInited && gisInited) {
              document.getElementById('authorize_button').style.visibility = 'visible';
            }
          }
    
          function handleAuthClick() {
            tokenClient.callback = async (resp) => {
              if (resp.error !== undefined) {
                throw (resp);
              }
              document.getElementById('signout_button').style.visibility = 'visible';
              document.getElementById('authorize_button').innerText = 'Refresh';
              await listFiles();
            };
    
            if (gapi.client.getToken() === null) {
              // Prompt the user to select a Google Account and ask for consent to share their data
              // when establishing a new session.
              tokenClient.requestAccessToken({prompt: 'consent'});
            } else {
              // Skip display of account chooser and consent dialog for an existing session.
              tokenClient.requestAccessToken({prompt: ''});
            }
          }
    
          /**
           *  Sign out the user upon button click.
           */
          function handleSignoutClick() {
            const token = gapi.client.getToken();
            if (token !== null) {
              google.accounts.oauth2.revoke(token.access_token);
              gapi.client.setToken('');
              document.getElementById('content').innerText = '';
              document.getElementById('authorize_button').innerText = 'Authorize';
              document.getElementById('signout_button').style.visibility = 'hidden';
            }
          }
    
          /**
           * Print metadata for first 10 files.
           */
          async function listFiles() {
            let response;
            try {
              response = await gapi.client.drive.files.list({
                'pageSize': 10,
                'fields': 'files(id, name)',
              });
            } catch (err) {
              document.getElementById('content').innerText = err.message;
              return;
            }
            const files = response.result.files;
            if (!files || files.length == 0) {
              document.getElementById('content').innerText = 'No files found.';
              return;
            }
            // Flatten to string to display
            const output = files.reduce(
                (str, file) => `${str}${file.name} (${file.id}\n`,
                'Files:\n');
            document.getElementById('content').innerText = output;
          }
        </script>
        <script async defer src="https://apis.google.com/js/api.js" onload="gapiLoaded()"></script>
        <script async defer src="https://accounts.google.com/gsi/client" onload="gisLoaded()"></script>
      </body>
    </html>
    

    Sample3:创建文件

    HTTP请求

    Body的组装:

    用自定义boundary边界字符串标识每个部分,每部分都有两个连字符打头。

    此外,在结束位置,仍以自定义boundary边界字符串 + 两个连字符结尾。

    async function upload () {
      console.log('-------upload---token------', gapi.client.getToken())
      let callback
      var content = 'this is my secret'; // 新文件的正文
      var blob = new Blob([content], { type: "text/plain"});
      const boundary = '-------314159265358979323846';
      const delimiter = "\r\n--" + boundary + "\r\n";
      const close_delim = "\r\n--" + boundary + "--";
    
      var reader = new FileReader();
      reader.readAsBinaryString(blob);
      reader.onload = function(e) {
        var contentType = 'application/octet-stream';
        var metadata = {
          'name': 'aaa.txt',
          'mimeType': contentType
        };
    
        var base64Data = btoa(reader.result);
        var multipartRequestBody =
            delimiter +
            'Content-Type: application/json\r\n\r\n' +
            JSON.stringify(metadata) +
            delimiter +
            'Content-Type: ' + contentType + '\r\n' +
            'Content-Transfer-Encoding: base64\r\n' +
            '\r\n' +
            base64Data +
            close_delim;
    
        var request = gapi.client.request({
            'path': '/upload/drive/v3/files',
            'method': 'POST',
            'params': {'uploadType': 'multipart'},
            'headers': {
              'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
            },
            'body': multipartRequestBody});
        if (!callback) {
          callback = function(file) {
            console.log(file)
          };
        }
        request.execute(callback);
      }
    }
    

    axios请求

    formData组装顺序:

    Meatadata >> file

    否则,会报错https://developers.google.com/drive/api/guides/manage-uploads#http_1

      var formData = new FormData();
      var content = 'this is my secret'; // 新文件的正文
      var blob = new Blob([content], { type: "text/plain"});
      var metadata = {
        'name': 'customfile.txt', // Filename at Google Drive
        'mimeType': 'text/plain', // mimeType at Google Drive
        // TODO [Optional]: Set the below credentials
        // Note: remove this parameter, if no target is needed
        // 'parents': ['SET-GOOGLE-DRIVE-FOLDER-ID'], // Folder ID at Google Drive which is optional
      };
      formData.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' }));
      formData.append("file", blob);
      axios.post(
        'https://www.googleapis.com/upload/drive/v3/files',
        formData,
        {
          headers: {
            Authorization: `Bearer ${access_token}`,
            'Content-Type': 'multipart/form-data'
          },
          params: {
            uploadType: 'multipart',
            supportsAllDrives: true
          },
        }
      )
    

    Sample4: 创建文件夹

    var parentId = '';//some parentId of a folder under which to create the new folder
    var fileMetadata = {
      'name' : 'New Folder',
      'mimeType' : 'application/vnd.google-apps.folder',
      'parents': [parentId]
    };
    gapi.client.drive.files.create({
      resource: fileMetadata,
    }).then(function(response) {
      switch(response.status){
        case 200:
          var file = response.result;
          console.log('Created Folder Id: ', file.id);
          break;
        default:
          console.log('Error creating the folder, '+response);
          break;
        }
    });
    

    Sample5:读取文件内容

    追加?alt=media可查看文件内容,否则,返回文件的metadata。

    async function handleExport (_event: any, fileId = '') {
      const res = await axios.get(
        `https://www.googleapis.com/drive/v3/files/${fileId}`,
        {
          params: {
            alt: 'media'
          },
          headers: {
            Authorization: `Bearer ${accessToken}`,
          },
        }
      )
      if (res.status === 200) {
        return res.data
      }
    }
    

    Sample6: 获取用户信息

    查看用户所有信息,可传fields: "*"

    async function handleUserInfo () {
      const res = await gapi.client.drive.about.get({
        fields: "user, kind"
      });
      console.log('-------------uesr--------', res)
    }
    

    相关文档

    相关文章

      网友评论

          本文标题:Google Development Api功能开发使用示例

          本文链接:https://www.haomeiwen.com/subject/mwgvqdtx.html