Как добавить / создать / вставить файлы в Google Drive через API?
Нужна помощь в отношении вставки файла на Google Drive через API. В документации API для этой цели нет четкого объяснения того, как отправить фактическое тело файла через запрос HTTP post.
5 ответов
Документация по операциям вставки уже содержит примеры на нескольких языках программирования. Вот как это сделать, используя протокол HTTP API Google Drive.
Сначала поместите новые метаданные файла в конечную точку накопителя. Он должен быть в форме объекта JSON Файлового ресурса:
POST /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer <OAuth 2.0 access token here>
...
{
"title": "file_name.extension",
"mimeType": "mime/type",
"description": "Stuff about the file"
}
Тело ответа будет представлением JSON вновь созданного ресурса File. Это будет выглядеть так:
{
"kind": "drive#file",
"id": string,
"etag": etag,
"selfLink": string,
"title": "file_name",
"mimeType": "mime/type",
"description": "Stuff about the file"
...
"downloadUrl": string,
...
}
Это подтверждение того, что запись файла была создана. Теперь вам нужно загрузить контент. Для этого вам нужно взять идентификатор файла, заданный атрибутом id JSON в приведенном выше ответе, и ЗАДАТЬ содержимое фактического файла в конечную точку выгрузки с авторизованным запросом OAuth 2.0. Это должно выглядеть так:
PUT /upload/drive/v2/files/{id}?uploadType=media HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer <OAuth 2.0 access token here>
Content-Type: mime/type
<file content here>
Вы сделали:)
Существует также способ сделать это в одном отдельном запросе POST, используя многокомпонентный запрос, когда вы публикуете метаданные файла одновременно с содержимым. Вот пример:
POST /upload/drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer <OAuth 2.0 access token here>
Content-Type: multipart/form-data; boundary=287032381131322
...
--287032381131322
Content-Type: application/json
{
"title": "file_name.extension",
"mimeType": "mime/type",
"description": "Stuff about the file"
}
--287032381131322
Content-Type: mime/type
<file content here>
--287032381131322--
Ответ будет содержать метаданные вновь созданного файла. Вы также можете использовать заголовок Content-Transfer-Encoding: base64 в части запроса, чтобы иметь возможность передавать данные файла в кодировке Base 64.
Наконец, есть также протокол возобновляемой загрузки, который удобен для загрузки больших файлов, предлагает функцию паузы / возобновления и / или загрузки файлов с нестабильным интернет-соединением.
PS: большая часть этого теперь описана в документации загрузки файла Drive.
Спасибо за объяснение! Это заняло у меня много часов, чтобы ходить по кругу с дрянной документацией Google SDK (извините, мне пришлось вывести свою напыщенную речь).
Вот функция, которую я сделал, которая будет обновлять текстовый файл (как вы видите, я обновляю html):
function gd_updateFile(fileId, folderId, text, callback) {
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var contentType = "text/html";
var metadata = {'mimeType': contentType,};
var multipartRequestBody =
delimiter + 'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter + 'Content-Type: ' + contentType + '\r\n' + '\r\n' +
text +
close_delim;
if (!callback) { callback = function(file) { console.log("Update Complete ",file) }; }
gapi.client.request({
'path': '/upload/drive/v2/files/'+folderId+"?fileId="+fileId+"&uploadType=multipart",
'method': 'PUT',
'params': {'fileId': fileId, 'uploadType': 'multipart'},
'headers': {'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'},
'body': multipartRequestBody,
callback:callback,
});
}
Это гибридный пример Google (который использует бинарный файл из загрузки) и хорошее объяснение от @Nivco выше.
4 года спустя это все еще трудно понять. Я взял ответ @user1158023, чтобы поддержать загрузку изображений. Я использую API v3 и superagent.js, чтобы помочь мне (поскольку gapi.client.request отправляет запрос на content.googleapis.com!?). Надеюсь, кто-то может найти это полезным.
function gd_uploadFile(name, contentType, data, callback) {
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
contentType = contentType || "text/html";
var metadata = {
name: name,
'mimeType': contentType
};
var multipartRequestBody =
delimiter + 'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n';
//Transfer images as base64 string.
if (contentType.indexOf('image/') === 0) {
var pos = data.indexOf('base64,');
multipartRequestBody += 'Content-Transfer-Encoding: base64\r\n' + '\r\n' +
data.slice(pos < 0 ? 0 : (pos + 'base64,'.length));
} else {
multipartRequestBody += + '\r\n' + data;
}
multipartRequestBody += close_delim;
if (!callback) { callback = function(file) { console.log("Update Complete ", file) }; }
superagent.post('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart').
set('Content-Type', 'multipart/form-data; boundary="' + boundary + '"').
set('Authorization', 'Bearer ' + gapi.auth.getToken().access_token).
send(multipartRequestBody).
end(function () {
console.log(arguments);
});
}
//On upload
$('#file')[0].onchange = function () {
var file = $('#file')[0].files[0];
if (file && file.type === 'image/jpeg') {
var reader = new FileReader();
reader.onloadend = function () {
var data = reader.result;
gd_uploadFile('img.jpg', 'image/jpeg', data, function () {
console.log(arguments);
});
}
reader.readAsDataURL(file);
}
};
index.html
...
<form>
<span>Upload: </span><input id="file" type="file" name="myFile">
</form>
...
Я хочу, чтобы были лучшие примеры для диска gapis v3... Мне потребовалось некоторое время, чтобы выяснить, как загрузить новый контент в существующий файл, созданный с помощью
gapi.client.drive.files.create({ "name" : "savefile.txt" }).execute(function(file) { console.log("Created file " + file.name + " id: " + file.id); });
но в конце концов я попробовал "счастливую" комбинацию добавления fileId к пути и изменения метода на PATCH
function uploadFile(id, text)
{
var auth_token = gapi.auth.getToken().access_token;
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var metadata = {
description : 'savefile for my game',
'mimeType': 'application/json'
};
var multipartRequestBody =
delimiter + 'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter + 'Content-Type: application/json\r\n\r\n' +
text +
close_delim;
gapi.client.request
( {
'path': '/upload/drive/v3/files/'+id,
'method': 'PATCH',
'params': {'fileId': id, 'uploadType': 'multipart'},
'headers': { 'Content-Type': 'multipart/form-data; boundary="' + boundary + '"', 'Authorization': 'Bearer ' + auth_token, },
'body': multipartRequestBody
}).execute(function(file) { console.log("Wrote to file " + file.name + " id: " + file.id); });
}
Но я предполагаю, что теперь вся документация по адресу https://developers.google.com/drive/v3/reference/files/update начинает иметь смысл для меня:-)
Команда Google Drive API выпустила версию 3 в конце 2015 года, и в этом выпуске insert()
изменил имена на create()
чтобы лучше отразить файловую операцию. Также была улучшена документация: теперь есть специальное руководство, посвященное загрузкам (простым, многокомпонентным и возобновляемым), которое поставляется с примерами кода на Java, Python, PHP, C#/.NET, Ruby, JavaScript/Node.js и iOS/Obj-C для загрузки обычного файла и еще один для импорта CSV-файла в виде Google Sheet.
Просто, чтобы показать это просто, ниже одно альтернативное решение Python (к примеру в документах) для коротких файлов ("простая загрузка"), где вам не нужно apiclient.http.MediaFileUpload
учебный класс. Этот фрагмент предполагает, что ваш код авторизации работает там, где ваша конечная точка службы DRIVE
с минимальным объемом аутентификации https://www.googleapis.com/auth/drive.file
,
# filenames & MIMEtypes
DST_FILENAME = 'inventory'
SRC_FILENAME = DST_FILENAME + '.csv'
SHT_MIMETYPE = 'application/vnd.google-apps.spreadsheet'
CSV_MIMETYPE = 'text/csv'
# Import CSV file to Google Drive as a Google Sheets file
METADATA = {'name': DST_FILENAME, 'mimeType': SHT_MIMETYPE}
rsp = DRIVE.files().create(body=METADATA, media_body=SRC_FILENAME).execute()
if rsp:
print('Imported %r to %r (as %s)' % (SRC_FILENAME, DST_FILENAME, rsp['mimeType']))
Обратите внимание: если вы пишете приложение для Android, существует отдельный API Google Drive для Android с собственным набором документов. Наконец, если вы используете JavaScript в Google Apps Script, как собственный объект Drive Drive, так и расширенная служба Drive по-прежнему используют v2 API.