在 Cordova 应用程序中实现 Dropbox API V2



我有一个Cordova应用程序,以前的Dropbox使用rossmartin/phonegap-dropbox-sync-android实现。现在,由于 API V1 将被弃用,我想升级到 Dropbox API V2。我已经使用 Dropbox API V2 搜索了 Cordova 应用程序的插件,但没有找到。所以我正在尝试使用 dropbox/dropbox-sdk-js 来实现它。

对于身份验证,我正在使用 authenticateWithCordova 方法,该方法返回我访问令牌(此处为完整文档(。一旦用户完成对 Dropbox 的身份验证,此方法将返回访问令牌,并使用重定向 URL 将用户重定向到 Cordova 应用程序。

当用户首次单击按钮时,此方法可以完美运行,但是当用户再次单击按钮时,调用此方法将显示空白屏幕并返回新的访问令牌。如何避免看到空白屏幕?

这是我从应用程序中调用的 Dropbox-sdk.js 文件中的方法,

DropboxBase.prototype.authenticateWithCordova = function (successCallback, errorCallback)
{
var redirect_url = 'https://www.dropbox.com/1/oauth2/redirect_receiver';
var url = this.getAuthenticationUrl(redirect_url);
var browser = window.open(url, '_blank');
var removed = false;
var onLoadError = function(event) {
// Try to avoid a browser crash on browser.close().
window.setTimeout(function() { browser.close() }, 10);
errorCallback();
}
var onLoadStop = function(event) {
var error_label = '&error=';
var error_index = event.url.indexOf(error_label);
if (error_index > -1) {
// Try to avoid a browser crash on browser.close().
window.setTimeout(function() { browser.close() }, 10);
errorCallback();
} else { 
var access_token_label = '#access_token=';
var access_token_index = event.url.indexOf(access_token_label);
var token_type_index = event.url.indexOf('&token_type=');
if (access_token_index > -1) {
access_token_index += access_token_label.length;
// Try to avoid a browser crash on browser.close().
window.setTimeout(function() { browser.close() }, 10);
var access_token = event.url.substring(access_token_index, token_type_index);
successCallback(access_token);
}
}
};

这是我用来调用该方法的代码,

function authenticateWithCordova()
{
var dbx = new Dropbox({ clientId: CLIENT_ID });
dbx.authenticateWithCordova(AuthSuccess,AuthFail);
}
function AuthSuccess(accessToken)
{   
localStorage.accessToken = accessToken;
}
function AuthFail()
{
alert("Auth Fail"); 
}

我昨天发现了一个模拟问题。这就是我解决它的方式。 首先,我将 var dbx 设置为全局。在我的索引中.js我把这些行放在 app.initialize(( 之后:

var CLIENT_ID = 'xxxxxxxxxxxxxxx';
var dbxt;
var dbx = new Dropbox({clientId: CLIENT_ID});

然后我检查 dbxt 是否为空:如果是,我使用 accessToken 创建一个新的 Dropbox 对象,否则我会使用已经建立的保管箱连接:

if (dbxt == null) {
dbx.authenticateWithCordova(function (accessToken) {
dbxt = new Dropbox({accessToken: accessToken});
dbxt.filesUpload({
path: '/mydump.sql',
contents: sql,
mode: 'overwrite',
mute: true
}).then(function (response) {
alert('Your backup has been successfully uploaded to your Dropbox!')
}).catch(function (error) {
alert('Error saving file to your Dropbox!')
console.error(error);
});
}, function (e){
console.log("failed Dropbox authentication");
}
}else{//dbxt already created
dbxt.filesUpload... //and the rest
}

这只是为了避免每次都创建新连接并获取新的访问令牌,我承认我不确定这是否是一种好的做法:我只知道在应用此代码之前,我收到了很多 Dropbox 服务器的错误请求响应:(

当我使用上面的代码时,在第一次登录后,我开始看到空白页面:这是 Dropbox OAuth2 用作重定向 URI(在 Dropbox 应用页面中设置为 https://www.dropbox.com/1/oauth2/redirect_receiver(的 inappbrowser 页面。

所以问题是如何使这个页面不可见。我发现了一个肮脏的技巧,对 inappbrowser .js脚本进行了小调整。 在脚本底部附近,紧接在这一行之前:

strWindowFeatures = strWindowFeatures || "";

我放了这个小块:

if (strUrl.indexOf('dropbox') > -1){
strWindowFeatures += "location=no,hidden=yes";
}

我本来希望只能使用"隐藏=是",但令人惊讶的是,如果我删除"位置=否",blkank 页面再次出现。

注意 1:您不必修改脚本 inappbrowser.js位于 plugins\cordova-plugin-inappbrowser\www\ 而是您在 platform\android\platform_www\plugins\cordova-plugin-inappbrowser\www\ 中找到的脚本

注意2:我现在找到了这个解决方法,所以我不能100%确定它是否完美运行。

注意 3:使 inappbrowser 页面不可见,具体取决于 Internet 连接,它可能看起来有一段时间什么都没有发生,因此您必须添加一些加载器来通知您的用户该应用程序正在运行。

希望这有帮助。

更新我刚刚意识到我们可以直接调整 dropbox-sdk 而不是 inappbrowser。

如果您将Dropbox与browserify一起使用,则必须打开dropbox-base.js并查找authenticateWithCordova((方法(它应该在第107行。然后更改行

var browser = window.open(url, '_blank');

var browser = window.open(url, '_blank', "location=no,hidden=yes");

如果您使用的是 Dropbox-sdk.min.js,则必须使用代码编辑器的搜索功能查找"window.open"。这将很容易,因为"window.open"只使用一次。因此,您必须更改以下内容:

i=window.open(n,"_blank"),

i=window.open(n,"_blank","location=no,hidden=yes"),

这似乎工作正常(我更喜欢在兴奋之前小心(。

更新2原谅以前的更新。我之前的检查:

if (strUrl.indexOf('dropbox') > -1){
strWindowFeatures += "location=no,hidden=yes";
}

是错误的,因为它使任何尝试连接到 Dropbox 的 inappbrowser 窗口不可见,因此它甚至会阻止我们登录 Dropbox。所以我们需要将其更改为

if (strUrl == 'https://www.dropbox.com/1/oauth2/redirect_receiver') {
strWindowFeatures += "location=no,hidden=yes";
}

这样,我们可以正确登录,并且下一个连接不会像我们想要的那样显示inappbrowser窗口。

所以总结一下:

  1. 忽略我的第一次更新
  2. 使用 UPDATE 2 在应用程序浏览器中修改 url 检查.js

请原谅我的困惑...

最新更新