0

我正在使用 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=value1&shareWith=value2&shareWith=value3

4

3 回答 3

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 对象(它需要一个类似的 JS 对象{ param1: 'one', param2: 'two' })并将每个 param 对象键传递给此方法调用中的键。检查值是否是一个数组是不够聪明的,如果是,则附加多个 Content-Disposition 行 - 正如您从 for 语句中看到的那样,它假定每个键只是一个字符串。而且由于选项字典不能有多个具有相同键的值,因此不能使用具有相同名称的 Content-Disposition 行创建表单,这是您需要提交多值参数的方式。

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

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

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

于 2013-04-17T17:00:56.347 回答
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
    }
}
于 2013-04-15T20:33:10.653 回答
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]})
于 2013-04-15T20:34:16.257 回答