Cordova FileUploadOptions 参数未在 iOS 上发布
Cordova FileUploadOptions params not posted on iOS
使用使用 build.phonegap.com 构建的应用程序,我发现 FileUploadOptions.params 值未发布 - iOS (8.4.1) 仅发布文件多部分数据。这不是服务器端错误,因为我看过 POST 使用 tcpdump/Wireshark 和 netcat。
使用:
- PhoneGap v.3.7.0
- 离子框架 v.1.0.1
- AngularJS v.1.3.13
这是用于上传测试文件的代码。它会生成一个临时文件并尝试上传它。问题是,我是不是弄错了什么,或者这是一个真正的错误?
$scope.doUploadTest = function() {
var q = $q.defer();
var promise = q.promise;
var text = "Test file content: " + new Date();
$window.requestFileSystem(LocalFileSystem.TEMPORARY, text.length, function(fs) {
q.resolve(fs);
}, function(err) {
q.reject(err);
});
promise
.then(function(fs) {
var qFile = $q.defer();
fs.root.getFile("upload.tmp", {create: true, exclusive: false}, function(entry) {
qFile.resolve(entry);
}, function(err) {
qFile.reject(err);
});
return qFile.promise;
})
.then(function(entry) {
console.log("got file: " + entry.nativeURL);
var qWriter = $q.defer();
entry.createWriter(function(writer) {
qWriter.resolve({writer: writer, entry: entry});
}, function(err) {
qWriter.reject(err);
});
return qWriter.promise;
})
.then(function(response) {
var qWrite = $q.defer();
response.writer.onwriteend = function(evt) {
qWrite.resolve(response.entry);
};
response.writer.write(text);
return qWrite.promise;
})
.then(function(entry) {
$scope.error = entry;
var qUpload = $q.defer();
var options = new FileUploadOptions();
options.params = {
Value: {
list: [1, 2, 3],
text: "foo bar baz",
number: 1234
}
};
options.fileKey = "thefile";
options.fileName = entry.name;
options.mimeType = "text/plain";
options.chunkedMode = false;
options.headers = {
"X-Upload": (new Date()).toString()
};
var ft = new FileTransfer();
ft.upload(entry.nativeURL, "http://192.168.0.30:9100/", function(success) {
entry.remove();
qUpload.resolve(success);
}, function(err) {
entry.remove();
qUpload.reject(err);
}, options);
// Abort after 3 seconds
$timeout(function() {
console.log("Aborting upload - timed out");
ft.abort();
}, 3000);
return qUpload.promise;
})
.then(function(response) {
console.log("Upload succeeded");
$scope.error = response;
})
.catch(function(err) {
console.log("Upload failed");
$scope.error = err;
});
;
};
在 iPhone 6 (iOS v.8.4.1) 上提出的请求如下:
POST / HTTP/1.1
Host: 192.168.0.30:9100
Content-Type: multipart/form-data; boundary=+++++org.apache.cordova.formBoundary
Accept-Encoding: gzip, deflate
X-Upload: Tue Sep 01 2015 12:12:49 GMT+0100 (BST)
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 8_4_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12H321 (5348809648)
Content-Length: 261
Accept-Language: en-us
X-Requested-With: XMLHttpRequest
--+++++org.apache.cordova.formBoundary
Content-Disposition: form-data; name="thefile"; filename="upload.tmp"
Content-Type: text/plain
Content-Length: 58
Test file content: Tue Sep 01 2015 12:12:49 GMT+0100 (BST)
--+++++org.apache.cordova.formBoundary--
在摩托罗拉 Moto X(第 2 代,Android 5.1)上,请求是这样的:
POST / HTTP/1.1
Content-Type: multipart/form-data; boundary=+++++
X-Upload: Tue Sep 01 2015 12:52:24 GMT+0100 (BST)
User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1; XT1092 Build/LPE23.32-25.1)
Host: 192.168.0.30:9100
Connection: Keep-Alive
Accept-Encoding: gzip
Content-Length: 289
--+++++
Content-Disposition: form-data; name="Value"
{"list":[1,2,3],"text":"foo bar baz","number":1234}
--+++++
Content-Disposition: form-data; name="thefile"; filename="upload.tmp"
Content-Type: text/plain
Test file content: Tue Sep 01 2015 12:52:23 GMT+0100 (BST)
--+++++--
事实证明,params 对象只能包含 literal 属性,不能包含对象。 documentation 仅使用字符串值,但未明确说明不支持对象。
由于在 Android 上插件将对象序列化为 JSON 字符串,而在 iOS 上插件默默地转储它,因此这变得更加复杂。
所以,解决方案就是先序列化数据:
var options = new FileUploadOptions();
options.params = {
Value: JSON.stringify({
list: [1, 2, 3],
text: "foo bar baz",
number: 1234
})
};
使用使用 build.phonegap.com 构建的应用程序,我发现 FileUploadOptions.params 值未发布 - iOS (8.4.1) 仅发布文件多部分数据。这不是服务器端错误,因为我看过 POST 使用 tcpdump/Wireshark 和 netcat。
使用:
- PhoneGap v.3.7.0
- 离子框架 v.1.0.1
- AngularJS v.1.3.13
这是用于上传测试文件的代码。它会生成一个临时文件并尝试上传它。问题是,我是不是弄错了什么,或者这是一个真正的错误?
$scope.doUploadTest = function() {
var q = $q.defer();
var promise = q.promise;
var text = "Test file content: " + new Date();
$window.requestFileSystem(LocalFileSystem.TEMPORARY, text.length, function(fs) {
q.resolve(fs);
}, function(err) {
q.reject(err);
});
promise
.then(function(fs) {
var qFile = $q.defer();
fs.root.getFile("upload.tmp", {create: true, exclusive: false}, function(entry) {
qFile.resolve(entry);
}, function(err) {
qFile.reject(err);
});
return qFile.promise;
})
.then(function(entry) {
console.log("got file: " + entry.nativeURL);
var qWriter = $q.defer();
entry.createWriter(function(writer) {
qWriter.resolve({writer: writer, entry: entry});
}, function(err) {
qWriter.reject(err);
});
return qWriter.promise;
})
.then(function(response) {
var qWrite = $q.defer();
response.writer.onwriteend = function(evt) {
qWrite.resolve(response.entry);
};
response.writer.write(text);
return qWrite.promise;
})
.then(function(entry) {
$scope.error = entry;
var qUpload = $q.defer();
var options = new FileUploadOptions();
options.params = {
Value: {
list: [1, 2, 3],
text: "foo bar baz",
number: 1234
}
};
options.fileKey = "thefile";
options.fileName = entry.name;
options.mimeType = "text/plain";
options.chunkedMode = false;
options.headers = {
"X-Upload": (new Date()).toString()
};
var ft = new FileTransfer();
ft.upload(entry.nativeURL, "http://192.168.0.30:9100/", function(success) {
entry.remove();
qUpload.resolve(success);
}, function(err) {
entry.remove();
qUpload.reject(err);
}, options);
// Abort after 3 seconds
$timeout(function() {
console.log("Aborting upload - timed out");
ft.abort();
}, 3000);
return qUpload.promise;
})
.then(function(response) {
console.log("Upload succeeded");
$scope.error = response;
})
.catch(function(err) {
console.log("Upload failed");
$scope.error = err;
});
;
};
在 iPhone 6 (iOS v.8.4.1) 上提出的请求如下:
POST / HTTP/1.1 Host: 192.168.0.30:9100 Content-Type: multipart/form-data; boundary=+++++org.apache.cordova.formBoundary Accept-Encoding: gzip, deflate X-Upload: Tue Sep 01 2015 12:12:49 GMT+0100 (BST) Connection: keep-alive Accept: */* User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 8_4_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12H321 (5348809648) Content-Length: 261 Accept-Language: en-us X-Requested-With: XMLHttpRequest --+++++org.apache.cordova.formBoundary Content-Disposition: form-data; name="thefile"; filename="upload.tmp" Content-Type: text/plain Content-Length: 58 Test file content: Tue Sep 01 2015 12:12:49 GMT+0100 (BST) --+++++org.apache.cordova.formBoundary--
在摩托罗拉 Moto X(第 2 代,Android 5.1)上,请求是这样的:
POST / HTTP/1.1 Content-Type: multipart/form-data; boundary=+++++ X-Upload: Tue Sep 01 2015 12:52:24 GMT+0100 (BST) User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1; XT1092 Build/LPE23.32-25.1) Host: 192.168.0.30:9100 Connection: Keep-Alive Accept-Encoding: gzip Content-Length: 289 --+++++ Content-Disposition: form-data; name="Value" {"list":[1,2,3],"text":"foo bar baz","number":1234} --+++++ Content-Disposition: form-data; name="thefile"; filename="upload.tmp" Content-Type: text/plain Test file content: Tue Sep 01 2015 12:52:23 GMT+0100 (BST) --+++++--
事实证明,params 对象只能包含 literal 属性,不能包含对象。 documentation 仅使用字符串值,但未明确说明不支持对象。
由于在 Android 上插件将对象序列化为 JSON 字符串,而在 iOS 上插件默默地转储它,因此这变得更加复杂。
所以,解决方案就是先序列化数据:
var options = new FileUploadOptions();
options.params = {
Value: JSON.stringify({
list: [1, 2, 3],
text: "foo bar baz",
number: 1234
})
};