[英]How do I download a Google Sheet with Google Picker all in JavaScript?
I'm trying to implement Google Picker and the Google Drive API in JavaScript on my website. 我正在尝试在我的网站上用JavaScript实现Google Picker和Google Drive API。 Currently, I use a PHP script to fetch Google Drive documents, but it's using restricted scopes and I want to remove restricted scopes from my application. 目前,我使用PHP脚本来获取Google云端硬盘文档,但它使用的是受限范围,并且我想从应用程序中删除受限范围。
First, I got the Google Picker quickstart code working . 首先,我使用了Google Picker快速入门代码 。 I tried to add a Google Drive get using the access token that I fetched in the Google Picker code. 我尝试使用在Google Picker代码中获取的访问令牌添加Google Drive 。 Google Drive code comes over in the client.js, right? Google云端硬盘代码会出现在client.js中,对吗? Is the access token used in api.js compatible with the access token used for client.js? api.js中使用的访问令牌是否与client.js使用的访问令牌兼容?
I found an old Gist from six years ago and tried to integrate and update it. 我发现了六年前的旧Gist,并尝试对其进行集成和更新。 Here's my code right now. 现在是我的代码。 The gapi.client.drive.files.get
fails to get the file. 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.');
//}
}
And my script tags: 和我的脚本标签:
<!-- 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>
The problem is when you try to retrieve the downloadUrl attribute in file.downloadUrl, which is a field that doesn't exist anymore in the Drive API version 3 (It was in the version 2), check v2 [1] and v3 [2]. 问题是,当您尝试检索file.downloadUrl中的downloadUrl属性时,该字段在Drive API版本3(该版本2中已不存在)中不再存在,请检查v2 [1]和v3 [2] ]。
Instead, you should use the webContentLink attribute to download the file, which is available for files with binary content as images, pdf, etc, but not for google docs and sheets (it's only available the webViewLink attribute which is the url to the file) [2]. 相反,您应该使用webContentLink属性下载文件,该文件可用于具有二进制内容(例如图像,pdf等)的文件,但不适用于google docs和工作表(仅适用于webViewLink属性,即文件的网址) [2]。 For these cases (docs and sheets), you can implement the import method which works for convert google documents and returns the file object [3]. 对于这些情况(文档和表格),您可以实施import方法,该方法适用于转换google文档并返回文件对象[3]。 The import request would be like this: 导入请求将如下所示:
var request = gapi.client.drive.files.import({ 'fileId': fileId, 'mimeType': mimeType });
With mimeType for the target document you want (pdf, txt, etc). 使用mimeType作为所需的目标文档(pdf,txt等)。 Then, inside the callback, access the attribute using file.webContentLink as with the other cases. 然后,与其他情况一样,在回调内部,使用file.webContentLink访问属性。
[1] https://developers.google.com/drive/api/v2/reference/files [1] https://developers.google.com/drive/api/v2/reference/files
[2] https://developers.google.com/drive/api/v3/reference/files [2] https://developers.google.com/drive/api/v3/reference/files
[3] https://developers.google.com/drive/api/v3/reference/files/export [3] https://developers.google.com/drive/api/v3/reference/files/export
Through trial and error, I discovered that in order to load both the Google Picker (client:auth2) and the Google Drive API (gapi.client), the Google Picker must be initialized with a callback, and then the Google Drive API is initialized with a Promise that must be chained. 通过反复试验,我发现为了同时加载Google Picker(client:auth2)和Google Drive API(gapi.client),必须使用回调初始化Google Picker,然后初始化Google Drive API。与必须连锁的诺言。 If the Promise is not chained, then it will be unresolved and will not work. 如果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
}
}
With this code, it must check if the user is authorized for every execution. 使用此代码,它必须检查用户是否被授权执行每次执行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.