我有一个移动站点m.example.com --我希望访问者从Google中选择一个文件,并将其发送到承载m.example.com的服务器。本质上模拟一个简单的<input type="file">文件上传,就像在桌面上一样。
据我所知,工作流如下:
1)用户选择带有Picker的文件,将所选文件的元数据发送给我的网站客户端(即运行在电话/平板电脑上的HTML/Javascript )。
2)我通过ajax或仅通过表单隐藏字段将其发送到服务器
3)我的服务器向Google请求获取文件,然后将其存储在服务器的文件系统中
所以我需要帮助:
( a)上述步骤正确吗?还有其他方法吗?或者我甚至可以使用一个服务,允许我的站点用户从几个云存储提供程序中选择他们的文件?
( a)假设我的步骤是正确的,而且这是唯一的方法,那么我就被困在与API对话的部件服务器上了。
到目前为止,我已经按照这里- Google picker auth popup is being blocked放弃了选择器,并获得了文件URL。我还没有完成,我只是手动将文件URL放到我的下载脚本中。
我使用的是PHP,我想下载到服务器的文件可以是公共的,也可以是私有的,这取决于最终用户。
我迷失在API文档(如手册页,而不是google文档)中,我与started (调用这个API文档)和https://developers.google.com/drive/web/quickstart/quickstart-php (调用这个驱动文档)混淆了--这是两个不同的API吗?
我遵循API文档中的链接,并从这里安装了客户机:https://github.com/google/google-api-php-client,但是当尝试在驱动器文档上“步骤3:设置示例”时,我得到了许多错误,例如文件找不到,类没有找到,所以我认为therr是这里记录的两个不同的API/客户端--有人能指出正确的方向吗?
更新
我已经在这个started链接的github上重新安装了PHP
看起来是这样:

我第一次在示例目录中运行simplefileupload.php,只需要输入我的项目详细信息。
于是转到sample,在google根目录中创建了drive_rest_api_step_3.php (如屏幕抓取中所示)。
Got Fatal error: require_once(): Failed opening required 'src/Google_Client.php' (include_path='.:/usr/local/lib/php') in /path/to/google-api/drive_rest_api_step_3.php on line 5
库中没有,也没有Google_Client.php,但是是src/Google/Client.php,所以我编辑require_once来使用它。
现在获取Failed opening required 'src/contrib/Google_DriveService.php' --搜索该文件也没有结果,但是有一个src/Google/Service/Drive.php,,所以编辑示例来使用:
要求(在sample上)是:
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_DriveService.php';现在:
require_once 'src/Google/Client.php';
require_once 'src/Google/Service/Drive.php';现在得到Fatal error: Class 'Google_Service' not found in /path/to/google-api/src/Google/Service/Drive.php on line 32
这就是为什么我认为这两套指南存在问题,它们要么使用不同的库,要么sample过时了,尽管is说是2015年3月30日更新的。
发布于 2015-05-21 18:38:45
您是对的,驱动器快速启动指南已经过时,它指的是谷歌的PHP库的旧版本,它在Google上,而不是在GitHub上的更新版本。因此,快速启动指南不适用于您下载的PHP客户端库。此外,快速启动指南代码打算在PHP命令行模式下执行,而不是在服务器上执行。
为了回答这个问题,我给出了几个分答案:
在中使用Google客户端库
试一下这个页面:https://developers.google.com/api-client-library/php/auth/web-app,它有一个示例,演示如何使用新的OAuth库在用户的Google上列出文件,包括整个OAuth过程。
不幸的是,即使这样也有点过时(包含路径已经过时了,现在已经过时了)。因此(为了StackOverflow的完整性起见),下面是一些代码。我在我的web服务器根目录中使用了一个子目录drivetest;根据需要更改URL。
请注意,您需要在Google的开发人员控制台中获取"Web应用程序“的客户端ID,并下载JSON (必要时替换代码中的client_secrets.json )。
drivetest/quickstart.php
<?php
require_once 'google-api-php-client/src/Google/autoload.php';
session_start();
$client = new Google_Client();
$client->setAuthConfigFile('client_secrets.json');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
$drive_service = new Google_Service_Drive($client);
$files_list = $drive_service->files->listFiles(array())->getItems();
echo json_encode($files_list);
} else {
$redirect_uri = 'http://localhost/drivetest/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>drivetest/oauth2callback.php
<?php
require_once 'google-api-php-client/src/Google/autoload.php';
session_start();
$client = new Google_Client();
$client->setAuthConfigFile('client_secrets.json');
$client->setRedirectUri('http://localhost/drivetest/oauth2callback.php');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
if (! isset($_GET['code'])) {
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect_uri = 'http://localhost/drivetest/quickstart.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>使用Google文件选择器选择文件
对于用例,您最好使用Google https://developers.google.com/picker/docs/,它为您实现了整个浏览和选择文件的功能,并且只为文件提供了一个ID。所需步骤概要:
我们可以通过两种方式(客户端或服务器端)来完成这个任务:
方法1:客户端
使用这种方法,步骤1-3是在Javascript中完成的,只有步骤4是在PHP中完成的。使用此方法,我们甚至不需要PHP客户端库!
下面是一个示例(改编自上述链接和http://webdevrefinery.com/forums/topic/12931-dropbox-google-drive-file-pickers/中的示例代码):
picker.html
该文件在加载页面时启动文件编辑器,并将URL放入表单中。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Picker Example</title>
<script type="text/javascript">
// The Browser API key obtained from the Google Developers Console.
var developerKey = '';
// The Client ID obtained from the Google Developers Console. Replace with your own Client ID.
var clientId = ""
// Replace with your own App ID. (Its the first number in your Client ID)
var appId = ""
// Scope to use to access user's Drive items.
var scope = ['https://www.googleapis.com/auth/drive'];
var pickerApiLoaded = false;
var oauthToken;
// 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() {
window.gapi.auth.authorize(
{
'client_id': clientId,
'scope': scope,
'immediate': false
},
handleAuthResult);
}
function onPickerApiLoad() {
pickerApiLoaded = true;
createPicker();
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
oauthToken = authResult.access_token;
createPicker();
}
}
// Create and render a Picker object
function createPicker() {
if (pickerApiLoaded && oauthToken) {
var view = new google.picker.DocsView();
view.setIncludeFolders(true);
//view.setMimeTypes("image/png,image/jpeg,image/jpg");
var picker = new google.picker.PickerBuilder()
//.enableFeature(google.picker.Feature.NAV_HIDDEN)
//.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.setAppId(appId)
.setOAuthToken(oauthToken)
.addView(view)
.setDeveloperKey(developerKey)
.setCallback(pickerCallback)
.build();
picker.setVisible(true);
}
}
// A simple callback implementation.
function pickerCallback(data) {
if (data.action == google.picker.Action.PICKED) {
var fileId = data.docs[0].id;
gapi.client.load('drive', 'v2', function() {
var request = gapi.client.drive.files.get({
fileId: fileId
});
request.execute(processFile);
});
}
}
function processFile(file) {
var token = gapi.auth.getToken();
// console.log(file);
// console.log(token);
document.getElementById("fileurl").value = file.downloadUrl+"&access_token="+token.access_token;
}
</script>
</head>
<body>
<form action="submit.php" method="post">
<label for="fileurl">File Download URL</label><input type="text" name="fileurl" id="fileurl">
<input type="submit">
</form>
<!-- The Google API Loader script. -->
<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=loadPicker"></script>
<script type="text/javascript" src="https://apis.google.com/js/client.js"></script>
</body>
</html>然后,我们将表单提交给PHP脚本,以便在服务器上下载该文件。这里的诀窍是,我们还需要将访问令牌从客户端传递到服务器,因为用户没有在服务器端进行身份验证。令人惊讶的是,您可以简单地附加access_token参数来验证文件的下载,如上面所示。
submit.php
根据服务器支持的内容,使用file_get_contents或CURL。但是,这需要HTTPS支持才能工作。
<?php
$filename = 'temp.jpg';
$ch = curl_init($_POST['fileurl']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Should verify in production!
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$data = curl_exec($ch);
//echo 'Curl error: ' . curl_error($ch);
curl_close($ch);
file_put_contents($filename, $data);
?>一种更正式的方法(遵循downloadurl)是使用Authorization头单独发送授权令牌。修改上面的Javascript,分别发送下载URL和令牌,然后使用下面的代码。如果要使用file_get_contents,请参阅contents() and headers有关如何发送自定义标头的内容。请注意,您需要在令牌之前使用Bearer单词!
<?php
$filename = 'temp.jpg';
$ch = curl_init($_POST['fileurl']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '.$_POST['authtoken']));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$data = curl_exec($ch);
echo 'Curl error: ' . curl_error($ch);
curl_close($ch);
file_put_contents($filename, $data);
?>方法2:服务器端(使用PHP)
使用这种方法,步骤1、3和4是在PHP中完成的,只有步骤2是在Javascript中完成的。
quickstart.php
此页面检查会话中是否存在访问令牌,如果没有重定向用户以进行身份验证。如果有,它会显示选择器和表单。在选择Javascript代码中,注意使用的oAuthToken是从服务器获得的!资料来源:Use Google Picker without logging in with Google account (with OAuth).然后,该表单向此页面提交一个POST请求,然后下载该文件。
<?php
require_once 'google-api-php-client/src/Google/autoload.php';
session_start();
// Ref: https://developers.google.com/drive/v2/reference/files/get
function downloadFile($service, $file) {
$downloadUrl = $file->getDownloadUrl();
if ($downloadUrl) {
$request = new Google_Http_Request($downloadUrl, 'GET', null, null);
$httpRequest = $service->getClient()->getAuth()->authenticatedRequest($request);
if ($httpRequest->getResponseHttpCode() == 200) {
return $httpRequest->getResponseBody();
} else {
// An error occurred.
return null;
}
} else {
// The file doesn't have any content stored on Drive.
return null;
}
}
$client = new Google_Client();
$client->setAuthConfigFile('client_secrets.json');
$client->addScope(Google_Service_Drive::DRIVE_READONLY);
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
if (isset($_POST['fileid'])){
$drive_service = new Google_Service_Drive($client);
$file = $drive_service->files->get($_POST['fileid']);
$data = downloadFile($drive_service, $file);
file_put_contents('temp.jpg', $data);
echo "file uploaded";
exit();
}
} else {
$redirect_uri = 'http://localhost/drivepicker-php/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
exit();
}
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Picker Example</title>
<script type="text/javascript">
// The Browser API key obtained from the Google Developers Console.
var developerKey = '';
// Replace with your own App ID. (Its the first number in your Client ID)
var appId = ""
var pickerApiLoaded = false;
// Use the Google API Loader script to load the google.picker script.
function loadPicker() {
gapi.load('picker', {'callback': onPickerApiLoad});
}
function onPickerApiLoad() {
pickerApiLoaded = true;
createPicker();
}
// Create and render a Picker object
function createPicker() {
if (pickerApiLoaded) {
var view = new google.picker.DocsView();
view.setIncludeFolders(true);
//view.setMimeTypes("image/png,image/jpeg,image/jpg");
var picker = new google.picker.PickerBuilder()
//.enableFeature(google.picker.Feature.NAV_HIDDEN)
//.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.setAppId(appId)
.setOAuthToken('<?= json_decode($client->getAccessToken())->access_token; ?>')
.addView(view)
.setDeveloperKey(developerKey)
.setCallback(pickerCallback)
.build();
picker.setVisible(true);
}
}
// A simple callback implementation.
function pickerCallback(data) {
if (data.action == google.picker.Action.PICKED) {
var fileId = data.docs[0].id;
document.getElementById("fileid").value = fileId;
}
}
</script>
</head>
<body>
<form action="quickstart.php" method="post">
<label for="fileid">File ID</label><input type="text" name="fileid" id="fileid">
<input type="submit">
</form>
<!-- The Google API Loader script. -->
<script type="text/javascript" src="https://apis.google.com/js/api.js?onload=loadPicker"></script>
<script type="text/javascript" src="https://apis.google.com/js/client.js"></script>
</body>
</html>oauth2callback.php
OAuth回调的助手文件。
<?php
require_once 'google-api-php-client/src/Google/autoload.php';
session_start();
$client = new Google_Client();
$client->setAuthConfigFile('client_secrets.json');
$client->setRedirectUri('http://localhost/drivepicker-php/oauth2callback.php');
$client->addScope(Google_Service_Drive::DRIVE_READONLY);
if (!isset($_GET['code'])) {
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect_uri = 'http://localhost/drivepicker-php/quickstart.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>https://stackoverflow.com/questions/30373856
复制相似问题