首先,让我们明确一点:没有形式,没有文件输入。我需要上传的图像文件是通过cordova相机API获得的。没有任何用户文件选择。我明确地提到这一点,因为大多数这类问题涉及用户使用带有文件输入元素的表单并选择文件。这不是我需要做的。
其次使用的技术是:
换句话说,Android 4.0上的混合HTML5应用程序
我的代码在android 4.3上运行 - 没问题。
不幸的是,4.0不支持Blob
构造函数,这是我的问题的开始。
使用弃用的BlobBuilder
API(可在4.0上获得),我似乎能够构建一个Blob。
但是,二进制图像数据只是没有进入对服务器的请求(我创建了一个虚拟接收器Servlet,它只是简单地将收到的POST主体转储到控制台 - 所有其他字段都存在,但是file
字段没有二进制内容)。
Blob创建代码:
try {
imgBlob = new Blob ([data],{type:'image/' + imageExt});
}
catch (e) {
$log.info('Apparently Blob constructor not supported, attempting fallback to BlobBuilder API');
window.BlobBuilder = window.BlobBuilder ||
window.WebKitBlobBuilder ||
window.MozBlobBuilder ||
window.MSBlobBuilder;
$log.debug('Selected BlobBuilder: ' + window.BlobBuilder);
if(e.name === 'TypeError' && window.BlobBuilder){
$log.debug ('We got exception TypeError');
var bb = new BlobBuilder();
bb.append(data);
imgBlob = bb.getBlob('image/' + imageExt);
}
else if(e.name === 'InvalidStateError'){
$log.debug ('We got exception InvalidStateError');
// InvalidStateError (tested on FF13 WinXP)
imgBlob = new Blob( data.buffer, {type : 'image/'+imageExt});
}
else{
$log.error ('We\'re screwed, blob constructor unsupported entirely');
}
}
data
参数是一个ArrayBuffer对象。据我所知,它包含正确的图像数据。
实际的上传代码:
var uploadUrl ='https://uploadReceiverUrl' ,
requestData = {
file: {val:imgBlob,contentDisposition:imgMetaData.uuid + '.' + imageExt},
imageid: imgMetaData.uuid,
formId: imgMetaData.formId,
key: theKey,
hmac: hmac,
userId: imgMetaData.userId
},
headers = {
'Content-Type':undefined
};
$http({
method : 'POST',
url : uploadUrl,
headers : headers,
data:requestData,
transformRequest: FormDataObject
})
.success (function (data,status) {
//Handle success by deleting image - this is fine.
})
.error (function (data, status) {
$log.warn ('UploadService.uploadImage():: failed. Status ' + status + ', data: ' + data);
});
提到的transformRequest
函数非常简单。基本上:
function (data) {
var fd = new FormData();
angular.forEach(data, function (value, key) {
if ( typeof value === 'object' ) {
fd.append(key, value.val, value.contentDisposition);
}
else {
fd.append(key, value);
$log.debug ('FormDataObject:: Added to FormData (' + key + ') with val (' + value + ')' );
}
}}
所以我要么错过了一些非常愚蠢或小的东西,要么Android 4.0中没有一些关键的支持我到目前为止都没有发现。
HALP?