Phonegap添加了多个相同键的FileTransfer参数,但值不同

时间:2013-04-12 21:24:41

标签: javascript cordova mobile query-string

我正在使用phonegap将文件上传到服务器,并且只运行一个例外...

var options = new FileUploadOptions();

options.fileKey = "file";
options.fileName = file.name;

var params = new Object();

if($scope.SelectedNames.length >0){
params.shareWith = SelectedNames[0].id;
//params.shareWith = [$scope.SelectNames[0].id,$scope.SelectNames[1].id]; 
}

options.params = params;

var ft = new FileTransfer();          
ft.upload(file.toURL(), "https://mysupersecret.url.com", win, fail, options, true);
//the rest of it

问题是有时我有多个“SelectedNames”需要添加到shareWith参数。如果我尝试将.shareWith设置为数组,则它不起作用。我自己尝试过创建POST查询字符串,但这也不起作用。显然只是调用一个额外的params.shareWith='xyz'只会覆盖第一个值。

思想?

我希望它提交一个查询字符串:

shareWith =值1&安培; shareWith =值2&安培; shareWith =值3

3 个答案:

答案 0 :(得分:0)

如何创建从SelectedNames数组上传的队列?一个完成后,将其从数组中移开,看看是否有任何剩余。示范:

// Start the queue
if(SelectedNames.length >0)
{
    runQueue();
}

function runQueue()
{
    if(SelectedNames.length > 0)
    {
        var options = new FileUploadOptions();

        options.fileKey = "file";
        options.fileName = file.name;

        var params = new Object();
        params.shareWith = SelectedNames[0].id;
        options.params = params;

        SelectedNames.shift();

        var ft = new FileTransfer();
        ft.upload(file.toURL(), "https://mysupersecret.url.com", runQueue, fail, options, true);

    }
    else
    {
        // ALL DONE
    }
}

答案 1 :(得分:0)

我会建议这样的事情:

params.shareWith0 = value1;
params.shareWith1 = value2;
params.shareWith2 = value3;
//...
params.shareWithCount = xy.Length;

或者您可以使用从未出现在您的值中的分隔符。

params.shareWith = [value1, value2, value3].join("~");

另一种更不干净的选择是使用jQuerys param()

$.param({shareWith: [value1, value2, value3]})

答案 2 :(得分:0)

PhoneGap中FileTransfer的当前实现使这很棘手,但它是可能的。问题是帖子中multipart/form-data的格式。为使服务器正确地将参数解释为多值,原始请求有效负载需要具有一系列具有相同名称的Content-Disposition行,如下所示:

--AaB03x
   Content-Disposition: form-data; name="shareWith[]"

   Joe

--AaB03x
   Content-Disposition: form-data; name="shareWith[]"

   Jim

--AaB03x
   Content-Disposition: form-data; name="shareWith[]"

   Jane

名称中的数组表示法表示该参数是多值的,服务器会将此参数解释为值数组,以您希望的方式。

不幸的是,这是Cordova库中的Objective-C代码,它将数据附加到请求有效负载:

    NSDictionary* options = [arguments objectAtIndex:5 withDefault:nil];
    ...
    for (NSString* key in options) {
            ...
            [postBodyBeforeFile appendData:[[NSString stringWithFormat:
                @"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] 
                dataUsingEncoding:NSUTF8StringEncoding]];

所有这一切都是遍历你的params对象(它需要像{ param1: 'one', param2: 'two' }这样的JS对象),并将每个param对象键传递给此方法调用中的键。检查查看值是否为数组是不够智能的,如果是,则追加多个Content-Disposition行 - 正如您在for语句中看到的那样,它假定每个键只是一个字符串。并且因为选项字典不能使用相同的键具有多个值,所以无法使用具有相同名称的Content-Disposition行创建表单,这是您需要提交多值参数的方式。

但是,您应该能够通过自己构建表单名称以不那么优雅的方式实现您想要的目标,如下所示:

params = {}
params['shareWith[0]'] = 'Joe';
params['shareWith[1]'] = 'Jim';
params['shareWith[2]'] = 'Jane';

服务器上的结果可能与上面的结果略有不同,但这应该可以帮助您完成大部分工作。希望将来能够解决这个问题,你将能够使用FileTransfer更合理地使用多值参数。