Dropbox прямой загрузки файлов из браузера
Я пытаюсь загрузить файлы напрямую в dropbox [из браузера / веб-приложения]. Функция "uploadFile" в API кода требует, чтобы файл был доступен для загрузки на сервере, это создает мне проблемы, потому что я не хочу никаких файлы для загрузки на мой сервер и оттуда в Dropbox.
$f = fopen("test.jpg", "rb"); // requires file on server
$result = $dbxClient->uploadFile("test.jpg", dbx\WriteMode::add(), $f);
fclose($f);
Попробовал этот https://github.com/dropbox/dropbox-js разочарован сказать, что нет четкой документации, многие ссылки на части документации не работает.
Мне нужно, чтобы файлы были загружены в мою учетную запись, и клиенты не должны входить в Dropbox.
Любые указатели будут по достоинству оценены. ищу методы Ajax / JavaScript.
Обновить
Я пробовал следующее, но нет ответа от Dropbox
HTML
<input type="file" name="file" id="file" onchange="doUpload(event)">
JavaScript
var doUpload = function(event){
var input = event.target;
var reader = new FileReader();
reader.onload = function(){
var arrayBuffer = reader.result;
$.ajax({
url: "https://api-content.dropbox.com/1/files_put/auto/uploads/" + input.files[0].name,
headers: {
Authorization: 'Bearer ' + MyAccessToken,
contentLength: file.size
},
crossDomain: true,
crossOrigin: true,
type: 'PUT',
contentType: input.files[0].type,
data: arrayBuffer,
dataType: 'json',
processData: false,
success : function(result) {
$('#uploadResults').html(result);
}
});
}
reader.readAsArrayBuffer(input.files[0]);
}
5 ответов
Большое спасибо @smarx с его указателями, я смог найти окончательное решение.
Также я добавил несколько дополнительных функций, таких как прослушивание процесса загрузки, чтобы пользователи могли отображать их в процентах.
HTML
<input type="file" name="file" id="file" onchange="doUpload(event)">
JavaScript
var doUpload = function(event){
var input = event.target;
var reader = new FileReader();
reader.onload = function(){
var arrayBuffer = reader.result;
var arrayBufferView = new Uint8Array( arrayBuffer );
var blob = new Blob( [ arrayBufferView ], { type: input.files[0].type } );
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL( blob );
$.ajax({
url: "https://api-content.dropbox.com/1/files_put/auto/YourDirectory/" + input.files[0].name,
headers: {
'Authorization':'Bearer ' +YourToken,
'Content-Length':input.files[0].size
},
crossDomain: true,
crossOrigin: true,
type: 'PUT',
contentType: input.files[0].type,
data: arrayBuffer,
dataType: 'json',
processData: false,
xhr: function()
{
var xhr = new window.XMLHttpRequest();
//Upload progress, litsens to the upload progress
//and get the upload status
xhr.upload.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = parseInt( parseFloat(evt.loaded / evt.total) * 100);
//Do something with upload progress
$('#uploadProgress').html(percentComplete);
$('#uploadProgressBar').css('width',percentComplete+'%');
}
}, false);
},
beforeSend: function(){
// Things you do before sending the file
// like showing the loader GIF
},
success : function(result) {
// Display the results from dropbox after upload
// Other stuff on complete
},
});
}
reader.readAsArrayBuffer(input.files[0]);
}
Вы использовали метод PUT, поскольку нашей единственной целью является загрузка файлов. Согласно моим исследованиям по различным ресурсам ( Stackru и zacharyvoase), метод put может передавать потоковые файлы большого размера, а также позволяет помещать файлы в указанный URI, если файл существует. файл должен быть заменен. Метод PUT нельзя переместить на другой URL-адрес, отличный от указанного URL-адреса.
Риск
Вы рискуете, используя токен доступа на стороне клиента, поэтому для маскировки токена должны быть предприняты строгие меры безопасности. Но современные инструменты Web-разработки, такие как консоли браузера, Firebug и т. Д., Могут отслеживать запросы вашего сервера и видеть ваш токен доступа.
Dropbox только что опубликовал блог с инструкциями о том, как это сделать. Вы можете найти его по адресу https://blogs.dropbox.com/developers/2016/03/how-formio-uses-dropbox-as-a-file-backend-for-javascript-apps/ (Полное раскрытие Сообщение блога.)
Вот как загрузить файл.
/**
* Two variables should already be set.
* dropboxToken = OAuth token received then signing in with OAuth.
* file = file object selected in the file widget.
*/
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(evt) {
var percentComplete = parseInt(100.0 * evt.loaded / evt.total);
// Upload in progress. Do something here with the percent complete.
};
xhr.onload = function() {
if (xhr.status === 200) {
var fileInfo = JSON.parse(xhr.response);
// Upload succeeded. Do something here with the file info.
}
else {
var errorMessage = xhr.response || 'Unable to upload file';
// Upload failed. Do something here with the error.
}
};
xhr.open('POST', 'https://content.dropboxapi.com/2/files/upload');
xhr.setRequestHeader('Authorization', 'Bearer ' + dropboxToken);
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.setRequestHeader('Dropbox-API-Arg', JSON.stringify({
path: '/' + file.name,
mode: 'add',
autorename: true,
mute: false
}));
xhr.send(file);
Затем, чтобы загрузить файл из Dropbox, сделайте это.
var downloadFile = function(evt, file) {
evt.preventDefault();
var xhr = new XMLHttpRequest();
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
if (xhr.status === 200) {
var blob = new Blob([xhr.response], {type: ’application/octet-stream’});
FileSaver.saveAs(blob, file.name, true);
}
else {
var errorMessage = xhr.response || 'Unable to download file';
// Upload failed. Do something here with the error.
}
};
xhr.open('POST', 'https://content.dropboxapi.com/2/files/download');
xhr.setRequestHeader('Authorization', 'Bearer ' + dropboxToken);
xhr.setRequestHeader('Dropbox-API-Arg', JSON.stringify({
path: file.path_lower
}));
xhr.send();
}
FileSaver и Blob не будут работать в старых браузерах, поэтому вы можете добавить к ним обходной путь.
Как уже отмечалось в других ответах, при каждой загрузке или загрузке файла сеанса должен быть доступ к токену Dropbox. Отправка чужого токена пользователю является проблемой безопасности, так как наличие токена даст ему полный контроль над учетной записью Dropbox. Единственный способ сделать это - дать каждому человеку пройти аутентификацию в Dropbox и получить свой собственный токен.
В Form.io мы реализовали аутентификацию и загрузку / выгрузку на нашу платформу. Это позволяет легко создавать веб-приложения с Dropbox в качестве бэкэнда для файлов.
"Мне нужно, чтобы файлы были загружены в мою учетную запись, и клиентам не нужно входить в Dropbox".
Тогда вам действительно нужно будет выполнить загрузку на стороне сервера. Для этого на стороне клиента будет означать отправку токена доступа в браузер, после чего любой пользователь вашего приложения сможет использовать этот токен доступа, чтобы сделать все, что он хочет с вашей учетной записью. (Например, удалите все остальные файлы, загрузите их частную коллекцию DVD и т. Д.)
По соображениям безопасности я настоятельно рекомендую выполнить загрузку на стороне сервера, где вы можете сохранить токен доступа в секрете.
Ответы, данные до сих пор, не используют javascript SDK Dropbox, который, я думаю, был бы лучшим способом сделать это. Проверьте эту ссылку здесь:
https://github.com/dropbox/dropbox-sdk-js/blob/master/examples/javascript/upload/index.html
который предоставляет пример, который часто зависит от загрузки SDK. (Правка: после игры с SDK я понимаю, что он создает POST-запрос, аналогичный принятому ответу в этом потоке. Однако популярный ответ пропускает присутствие предварительного вызова OPTIONS, который sdk делает до фактического POST)
Я мог бы также добавить, что то, что не показано в примерах Dropbox SDK, это то, что вы можете загрузить объект BLOB-объектов в Dropbox; это полезно, например, если вы хотите динамически извлекать изображения из холста и загружать их и не хотите загружать что-то, что было выбрано из файловой системы через ввод загруженного файла.
Вот краткий пример сценария, который я описываю:
//code below after having included dropbox-sdk-js in your project.
//Dropbox is in scope!
var dbx = new Dropbox.Dropbox({ accessToken: ACCESS_TOKEN });
//numerous stack overflow examples on creating a blob from data uri
var blob = dataURIToBlob(canvas.toDataUrl());
//the path here is the path of the file as it will exist on dropbox.
//should be unique or you will get a 4xx error
dbx.filesUpload({path: `unq_filename.png`, contents: blob})
upload.html
Загрузить
upload.js
$('#form_wizard_1 .button-submit').click(function () {
var ACCESS_TOKEN ="Your token get from dropbox";
var dbx = new Dropbox({ accessToken: ACCESS_TOKEN });
var fileInput = document.getElementById('files1');
var file = fileInput.files[0];
res=dbx.filesUpload({path: '/' + file.name, contents: file})
.then(function(response) {
var results = document.getElementById('results');
results.appendChild(document.createTextNode('File uploaded!'));
res=response;
console.log(response);
})
.catch(function(error) {
console.error(error);
});
}