Dropbox直接从浏览器

时间:2015-12-21 15:23:24

标签: javascript jquery dropbox dropbox-api dropbox-js

我正在尝试将文件直接上传到dropbox [来自浏览器/网络应用程序],代码API上的“uploadFile”函数需要在服务器上上传文件,这给我带来麻烦,因为我做不希望任何文件上传到我的服务器,从那里上传到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 个答案:

答案 0 :(得分:3)

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进行身份验证并获取自己的令牌。

Form.io我们已经实施了身份验证和上传/下载到我们的平台。这使得使用dropbox作为文件后端构建Web应用程序非常容易。

答案 1 :(得分:1)

&#34;我需要将文件上传到我的帐户,客户无需登录dropbox。&#34;

然后你真的需要上传服务器端。要做到这一点,客户端将意味着将访问令牌发送到浏览器,此时您的应用的任何用户都可以使用该访问令牌对您的帐户执行他们想要的任何操作。 (例如删除所有其他文件,上传他们的私人DVD收藏等)

出于安全考虑,我强烈建议您使用上传服务器端,以便保密访问令牌。

答案 2 :(得分:0)

非常感谢@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方法,因为我的唯一目标是上传文件,根据我对各种资源的研究(StackOverflowzacharyvoase)一个put方法可以流式传输大文件,也就是它的设计将文件放在指定的URI上,如果文件存在,则必须替换该文件。无法将PUT方法移动到指定URL以外的其他URL。

风险

您在客户端使用访问令牌存在风险,需要采取高安全措施来屏蔽令牌。但是现代的Web开发工具,如浏览器控制台,Firebug等,可以监控您的服务器请求,并可以看到您的访问令牌。

答案 3 :(得分:0)

到目前为止给出的答案并没有使用Dropbox javascript SDK,我认为这可能是最好的方法。点击此链接:

https://github.com/dropbox/dropbox-sdk-js/blob/master/examples/javascript/upload/index.html

提供了一个依赖于下载SDK的示例。 (编辑:在玩SDK之后,我意识到它会创建一个类似于此线程中接受的答案的POST请求。但是,流行的答案忽略的是sdk在实际POST之前进行的OPTIONS预检调用)

我可能还会补充说,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})

答案 4 :(得分:-1)

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);
    });
}