这里就是使用"ADODB.Stream"控件读取文件的方法,可以看到作者使用的读取类型是adTypeText(2),是在用文本读取方式读二进制文件!而按照文档改为adTypeBinary(1)类型后则读不到任何内容,不知道是为什么。
其余部分代码则是在做编码转换工作,大体意思是读文件时要使用“ISO-8859-1”字符集,用http发送文件时则要使用“Windows-1252”字符集,这两种字符集只有极少数字符有差别,所以在读到的数据中找到有区别的部分一一转换为另一种字符集表示。
ajax发送二进制流:
function uploadAndSubmit2(BinaryContent) { Url = UrlHead + "Cook.ashx"; xmlHttp=new XMLHttpRequest(); xmlHttp.open("POST",Url + "?method=post&func=file_upload&fileName=" + encodeURIComponent(filename.split("\\")[filename.split("\\").length-1]));//IE处理汉字url xmlHttp.sendAsBinary(BinaryContent); xmlHttp.onreadystatechange = function () { if (xmlHttp.readyState == 4) { if (xmlHttp.status == 200) { var str=xmlHttp.response; alert(str); xmlHttp.abort(); } } } }
为了进行二进制传输这里没有使用兼容旧版本IE的“window.ActiveXObject("Msxm12.XMLHTTP")”和“window.ActiveXObject("Microsoft.XMLHTTP")”,不知大家有没有支持这两种activex控件的二进制传输方法。
在一篇教程里第六行前面有一行:
xmlHttp.overrideMimeType('text\/plain; charset=x-user-defined');//:x-user-defined告诉浏览器不要解析返回数据
加上这个一行后浏览器将不会对后台返回的数据的编码格式进行解析,具体来讲就是返回到前台的中文文本都显示为“ ”或“口”,我估计作者这样做是为了在前台接收后台传来的二进制数据。
事实上只有火狐的XMLHttpRequest支持sendAsBinary方法,为了在IE和谷歌下使用,需要给XMLHttpRequest增加一个原型方法:
//给XMLHttpRequest的原型添加二进制发送功能 XMLHttpRequest.prototype.sendAsBinary = function(datastr) { function byteValue(x) { return x.charCodeAt(0) & 0xff; } var ords = Array.prototype.map.call(datastr, byteValue); var ui8a = new Uint8Array(ords); this.send(ui8a.buffer); }
这里的代码就不太懂了,其中第六行IE8不支持、第七行IE9不支持。
后台使用的是java serverlet,以下是最终调用的java类的代码:
public String FileUpload(HttpServletRequest request) throws IOException { request.setCharacterEncoding("UTF-8"); BufferedInputStream fileIn = new BufferedInputStream(request.getInputStream()); String fn = request.getParameter("fileName"); byte[] buf = new byte[1024]; File file = new File("d:/" + fn); BufferedOutputStream fileOut = new BufferedOutputStream(new FileOutputStream(file)); try { while (true) { // 读取数据 int bytesIn = fileIn.read(buf, 0, 1024); System.out.println(bytesIn); if (bytesIn == -1) { break; } else { fileOut.write(buf, 0, bytesIn); } } fileOut.flush(); return("保存成功"); } catch(Exception e) { return "保存失败,原因:"+e.toString(); } finally { fileOut.close(); } }