我正在使用Prototype提交POST请求,而postdata包含许多字段,其中一个是来自文件的二进制数据(在这种情况下是用户选择上传的Excel电子表格。)
我使用HTML5 FileReader接口通过$query= "SELECT * FROM `table`";
$mysqliResult= $mysqli->query($query);
if(get_resource_type($mysqliResult) === 'mysqli result') {
}
获取文件的内容,效果很好。如果我使用FileReader.readAsBinaryString()
打印字符串中的各种字符,那么它们会显示出预期的值。
但是,一旦我将此字符串数据放入一个对象(以及其他表单字段)并将其作为charCodeAt()
选项传递给Prototype的parameters
,数据就会损坏。某些字符值(如Ajax.Request()
)将替换为0x82
,0xC2 0x82
将替换为0xAC
,依此类推。
我尝试使用0xC2 0xAC
对字符串进行base64编码,但是window.atob()
失败了,所以很明显我需要避免某种处理。
有没有人知道如何通过Prototype的InvalidCharacterError: String contains an invalid character
传递二进制数据,同时还在同一请求中包含其他表单字段?
答案 0 :(得分:1)
要进行ajax文件上传,您应该使用FormData对象
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
// timeouts
con.setConnectTimeout(5000);
con.setReadTimeout(5000);
con.setRequestMethod("put");
con.setDoInput(true);
con.setDoOutput(true);
con.setRequestProperty("Content-length", String.valueOf(output.length()));
OutputStreamWriter os = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
BufferedWriter writer = new BufferedWriter(os);
writer.write(output);
writer.close();
os.close();
con.connect();
int respCode = con.getResponseCode();
if(respCode == 200) {
InputStreamReader is = new InputStreamReader(con.getInputStream());
BufferedReader br = new BufferedReader(is);
String input;
String respBody = "";
while ((input = br.readLine()) != null){
respBody += input;
}
br.close();
is.close();
this.result = respBody;
}
使用此方法,服务器将看到请求,就好像它是由具有属性var data = new FormData();
//var data = new FormData(someForm); if all your fields is in an html form
// add fields to form
data.append('fieldname',fieldvalue);
data.append('filefieldname',fileobject);
//etc
new Ajax.Request(url, {
contentType: null,
method: 'post',
postBody: data,
onSuccess: successFunction
})
的表单发送的
答案 1 :(得分:0)
这样做需要魔法和小精灵粉尘。 (好吧,不是真的)
首先,您需要将表单字段值作为URL参数而不是POST,然后使用文件内容覆盖帖子正文。例如
new Ajax.Request('/url.php?rawupload=1&id='+$F('id')+'&label='+label,
{
'method':'post',
'postBody':fileobject,
'onSuccess':function() { alert('success'); }
});
fileobject
是从文件上传输入元素
是的,如果你有很多表单字段,它不是最优雅的解决方案。如果你有很多表单字段来构建查询字符串而不是手工完成,你也可以使用Hash#toQueryString
http://api.prototypejs.org/language/Hash/prototype/toQueryString/