【问题标题】:How do I download a Google Sheet with Google Picker all in JavaScript?如何在 JavaScript 中使用 Google Picker 下载 Google Sheet?
【发布时间】:2019-06-17 14:18:36
【问题描述】:

我正在尝试在我的网站上用 JavaScript 实现 Google Picker 和 Google Drive API。目前,我使用 PHP 脚本来获取 Google Drive 文档,但它使用的是受限范围,我想从我的应用程序中删除受限范围。

首先,我得到了Google Picker quickstart code working。我尝试使用在 Google Picker 代码中获取的访问令牌添加 Google Drive get。 Google Drive 代码在 client.js 中,对吗? api.js 使用的访问令牌是否与 client.js 使用的访问令牌兼容?

我找到an old Gist from six years ago 并尝试集成和更新它。这是我现在的代码。 gapi.client.drive.files.get 获取文件失败。

// Scope to use to access user's photos.
var scope = 'https://www.googleapis.com/auth/drive.file';

var pickerApiLoaded = false;
var driveApiLoaded = false;
var oauthToken;

// Use the API Loader script to load google.picker and gapi.auth.
function onApiLoad() {
    gapi.load('auth2', onAuthApiLoad);
    gapi.load('picker', onPickerApiLoad);
}

function onClientLoad() {
    gapi.client.setApiKey(developerKey);
    gapi.client.load('drive', 'v2', onDriveApiLoad);
}

function onAuthApiLoad() {
    var authBtn = document.getElementById('auth');
    authBtn.disabled = false;
    authBtn.addEventListener('click', function() {
        gapi.auth2.init({ client_id: clientId }).then(function(googleAuth) {
            googleAuth.signIn({ scope: scope }).then(function(result) {
                handleAuthResult(result.getAuthResponse());
            })
        })
    });
}

function onPickerApiLoad() {
    pickerApiLoaded = true;
    createPicker();
}

function onDriveApiLoad() {
    driveApiLoaded = true;
}

function handleAuthResult(authResult) {
    if (authResult && !authResult.error) {
        oauthToken = authResult.access_token;
        createPicker();
    }
}

// Create and render a Picker object for picking user Photos.
function createPicker() {
    if (pickerApiLoaded && oauthToken) {
        var view = new google.picker.DocsView(google.picker.ViewId.SPREADSHEETS);
        //view.setMimeTypes("text/csv");
        //view.setMode(google.picker.DocsViewMode.LIST);
        view.setQuery(jQuery('[updateparam="name"]').val());

        var picker = new google.picker.PickerBuilder().
                //addView(google.picker.ViewId.DOCS).
                addView(view).
                setInitialView(view).
                setOAuthToken(oauthToken).
                setDeveloperKey(developerKey).
                setCallback(pickerCallback).
                build();
        picker.setVisible(true);
    }
}

// A simple callback implementation.
function pickerCallback(data) {
    if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
        var doc = data[google.picker.Response.DOCUMENTS][0];
        var fileId = doc[google.picker.Document.ID];
        jQuery('[updateparam="googleDriveFileId"]').val(fileId);

        //if (driveApiLoaded) {
            var request = gapi.client.drive.files.get({
                'fileId': fileId
            });
            request.execute(function(file) {
                var xhr = new XMLHttpRequest();
                xhr.open('GET', file.downloadUrl);
                xhr.setRequestHeader('Authorization', 'Bearer ' + oauthToken);
                xhr.onload = function() {
                    console.log(xhr.responseText);
                };
                xhr.onerror = function() {
                    warningMessage.displayMessage('Failed to download Google Drive document ' + fileId);
                };          
            });
        //} else {
        //  warningMessage.displayMessage('Google Drive API has not been loaded.');
        //}
    }
    // Triggers before Picker is shown
    // else {
    //  warningMessage.displayMessage('No Google Drive document selected.');
    //}
}

还有我的脚本标签:

<!-- The Google API Loader script. -->
<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
<script type="text/javascript" src="https://www.google.com/jsapi?key=KEY"></script>
<script type="text/javascript" src="https://apis.google.com/js/client.js?onload=onClientLoad"></script>

【问题讨论】:

  • 我喜欢高素质的人,他们在没有任何建设性批评的情况下投出密切的选票,以评论我如何改进我的问题的形式。这是懦弱的。

标签: javascript google-api google-drive-api google-picker google-client


【解决方案1】:

问题是当您尝试检索 file.downloadUrl 中的 downloadUrl 属性时,该字段在 Drive API 版本 3(它在版本 2 中)中不再存在,请检查 v2 [1] 并v3 [2]。

相反,您应该使用 webContentLink 属性来下载文件,该属性可用于具有二进制内容的文件,如图像、pdf 等,但不适用于 google 文档和表格(它仅适用于 webViewLink 属性,它是文件)[2]。对于这些情况(文档和表格),您可以实现导入方法,该方法适用于转换谷歌文档并返回文件对象 [3]。导入请求是这样的:

var request = gapi.client.drive.files.import({ 'fileId': fileId, 'mimeType': mimeType });

使用 mimeType 作为您想要的目标文档(pdf、txt 等)。然后,在回调内部,像其他情况一样使用 file.webContentLink 访问属性。

[1]https://developers.google.com/drive/api/v2/reference/files

[2]https://developers.google.com/drive/api/v3/reference/files

[3]https://developers.google.com/drive/api/v3/reference/files/export

【讨论】:

  • 你抢我的答案!我昨天上午 11 点开始工作。我将编译我的解决方案,看看您的答案是否缺少任何内容。
  • [这个[(stackoverflow.com/a/57047076/904344) 是我想出的解决方案。我使用files.export 调用作为检查用户是否有权查看drive.file 权限下的文件的简写。
【解决方案2】:

通过反复试验,我发现为了同时加载 Google Picker (client:auth2) 和 Google Drive API (gapi.client),Google Picker 必须通过回调初始化,然后是 Google Drive API 使用必须链接的 Promise 进行初始化。如果 Promise 没有被链接,那么它将是未解决的并且不会起作用。

// Use the Google API Loader script to load the google.picker script.
function loadPicker() {
    gapi.load('auth', {'callback': onAuthApiLoad});
    gapi.load('picker', {'callback': onPickerApiLoad});
}

function onAuthApiLoad() {
    driveApiLoaded = true;
}

function onPickerApiLoad() {
    pickerApiLoaded = true;
}

function askForClientAuthorization() {
    gapi.load('client:auth2', function(_) {
        window.gapi.client.init({
            apiKey: developerKey,
            clientId: clientId,
            discoveryDocs: ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"],
            scope: 'https://www.googleapis.com/auth/drive.file'
        })
        .then(function(__) {
            return gapi.client.drive.files.export({
                'fileId': window.googleDriveFileId,
                'mimeType': 'text/csv'
            })
            .then(function(file) {
                // Client is authorized to access this file, do something with the file
            })
            .catch(function(e) {
                gapi.auth.authorize(
                {
                    'client_id': clientId,
                    'scope': scope,
                    'immediate': false
                },
                handleAuthResult);
            });

        })
    })
}

function handleAuthResult(authResult) {
    if (authResult && !authResult.error) {
        oauthToken = authResult.access_token;
        createPicker();
        return true;
    } else {
        return false;
    }
}

// Create and render a Picker object for searching images.
function createPicker() {
    if (pickerApiLoaded && oauthToken) {
        var view = new google.picker.DocsView(google.picker.ViewId.SPREADSHEETS);
        view.setMode(google.picker.DocsViewMode.LIST);
        view.setQuery(window.dataFeedName);
        var picker = new google.picker.PickerBuilder()
                .setAppId(appId)
                .setOAuthToken(oauthToken)
                .addView(view)
                .setDeveloperKey(developerKey)
                .setCallback(pickerCallback)
                .build();
         picker.setVisible(true);
         return picker;
    }
}

// A simple callback implementation.
function pickerCallback(data) {
    if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
        // Do work
    }
}

使用此代码,它必须检查用户是否有权执行每次执行。

【讨论】:

    猜你喜欢
    • 2013-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-08
    • 2022-06-14
    • 1970-01-01
    • 2021-07-14
    • 2021-02-05
    相关资源
    最近更新 更多