可以将 Google APIs Javascript 客户端库与 Drive 一起使用,但您必须意识到存在一些痛点。
目前有两个主要问题,这两个问题都有解决方法:
授权
首先,如果您仔细了解 Google Drive 身份验证的工作原理,您会发现,在用户安装了您的 Drive 应用程序并尝试使用您的应用程序打开文件或创建新文件后,Drive 会自动启动 OAuth 2.0 授权流程并auth 参数设置为response_type=code和access_type=offline。这基本上意味着现在 Drive 应用程序被迫使用 OAuth 2 服务器端流程,这对 Javascript 客户端库(仅使用客户端流程)没有任何用处。
问题在于:Drive 启动服务器端 OAuth 2.0 流程,然后 Javascript 客户端库启动客户端 OAuth 2.0 流程。
这仍然可以工作,您所要做的就是使用服务器端代码来处理驱动器服务器端流程后返回的授权代码(您需要将其交换为访问令牌和刷新令牌)。这样,只有在第一个流程中才会提示用户进行授权。第一次交换授权码后,会自动绕过授权页面。
我们的文档中提供了执行此操作的服务器端示例。
如果您不在服务器端流程上处理/交换身份验证代码,则每次用户尝试从云端硬盘使用您的应用时,都会提示他进行身份验证。
处理文件内容
第二个问题是我们的 Javascript 客户端库无法轻松上传和访问实际的 Drive 文件内容。您仍然可以这样做,但您必须使用自定义 Javascript 代码。
读取文件内容
当检索文件元数据/文件对象时,它包含downloadUrl
指向实际文件内容的属性。现在可以使用 CORS 请求下载文件,最简单的身份验证方法是在 URL 参数中使用 OAuth 2 访问令牌。因此,只需使用 XHR 或通过将用户转发到 URL 来附加并获取&access_token=...
文件。downloadUrl
上传文件内容
更新更新:上传端点现在支持 CORS。
~~更新:与 Drive API 的其余部分不同,上传端点不支持 CORS,因此您现在必须使用以下技巧:~~
上传文件很棘手,因为它不是内置在 Javascript 客户端库中,而且您不能完全使用本响应中描述的 HTTP 来完成,因为我们不允许在这些 API 端点上进行跨域请求。因此,您必须利用我们的 Javascript 客户端库使用的 iframe 代理,并使用它向 Drive SDK 发送构建的多部分请求。感谢@Alain,我们在下面有一个如何做到这一点的示例:
/**
* Insert new file.
*
* @param {File} fileData File object to read data from.
* @param {Function} callback Callback function to call when the request is complete.
*/
function insertFileData(fileData, callback) {
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var reader = new FileReader();
reader.readAsBinaryString(fileData);
reader.onload = function(e) {
var contentType = fileData.type || 'application/octet-stream';
var metadata = {
'title': fileData.fileName,
'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/v2/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);
}
}
为了改善这一切,未来我们可能会:
- 让开发人员选择他们想要使用的 OAuth 2.0 流程(服务器端或客户端),或者让开发人员完全处理 OAuth 流程。
/upload/...
在端点上允许 CORS
exportLinks
在原生 gDocs上允许 CORS
- 我们应该使用我们的 Javascript 客户端库更容易上传文件。
虽然在这一点上没有承诺:)