使用ActiceX操作客户端文件

在项目开发时需要用到某扫描仪自带开发sdk,很坑的是只支持ie,唯一的好处是直接解决了扫描仪存到客户端的文件自动上传至服务器的功能,因为ie可以支持不安全的ActiveX,所以我为了解决扫描仪扫描至客户端的文件自动上传至服务器,使用了ActiveX。

最开始用了new ActiveXObject(“Scripting.FileSystemObject”)的getFile方法获得file对象,企图通过FormData结合ajax上传至服务器代码如下:

var fd = new FormData(),
    xhr = new XMLHttpRequest(),
    fso = new ActiveXObject('Scripting.FileSystemObject'),
    file = fso.GetFile('C:/xxx');
fd.append('file',file);
xhr.open('POST',url);
xhr.send(fd);

结果才发现,ie没有内置的h5的对象FormData,用的话需要blablabla各种操作,太麻烦,我决定横向解决,在网上查阅相关资料后发现利用adodb.stream可以将客户端文件装载到此对象中,于是试着将前台所需信息加上文件封装到xml中,通过ajax提交至服务器,代码如下:

// 创建XML对象,组合XML文档数据  
var xmlDOM = createDocument();  
xmlDOM.loadXML('<?xml version="1.0" encoding="GBK" ?> <root/>');  

// 创建ADODB.Stream对象  
var as = new ActiveXObject("adodb.stream") , fileSize , unitSize = 1024 , read_count , node , root;  

// 设置流数据类型为二进制类型  
as.Type = 1; // adTypeBinary  
// 打开ADODB.Stream对象  
as.Open();  
// 将本地文件装载到ADODB.Stream对象中  
as.LoadFromFile(localPath);  
// 获取文件大小(以字节为单位)  
fileSize = as.Size;  
// 获取文件分割数据单元的数量  
read_count = parseInt((fileSize/unitSize).toString())+parseInt(((fileSize%unitSize)==0)?0:1);  
/** other code... **/
// 创建XML元素节点,保存上传文件内容  
for(var i=0;i<read_count;i++)  
{  
        node = xmlDOM.createElement("uploadcontent");
        // 文件内容编码方式为Base64  
    node.dataType = "bin.base64";
    // 判断当前保存的数据节点大小,根据条件进行分类操作
    if((parseInt(fileSize%unitSize)!=0)&&(i==parseInt(read_count-1))){  
        // 当数据包大小不是数据单元的整数倍时,读取最后剩余的小于数据单元的所有数据  
        node.nodeTypedValue = as.Read();  
    }else{  
        // 读取一个完整数据单元的数据  
        node.nodeTypedValue = as.Read(unitSize);  
    }  
    root.appendChild(node);  
}  
/** other code ... **/ 
var xhr= window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHttp");  
// 打开Microsoft.XMLHTP对象  
xhr.open("post", targetUrl , false);  
// 使用Microsoft.XMLHTP对象上传文件  
xhr.send(xmlDOM);

下面是function createDocument:

function createDocument() {  
            var xmldom;  
            var versions = ['MSXML2.DOMDocument.6.0', 'MSXML2.DOMDocument.5.0','MSXML2.DOMDocument.4.0','MSXML2.DOMDocument.3.0', 'MSXML2.DOMDocument'],  
                i, len;  
            for (i = 0, len = versions.length; i < len; i++) {  
                try {  
                    xmldom = new ActiveXObject(versions[i]);  
                    if(xmldom != null)  
                        break;  
                } catch (ex) {  
                    //跳过  
                    console.log('创建document对象失败!');  
                }  
            }  
            return xmldom;  
        } 

服务器端代码:

int unit_size = 1024;
// 初始化xml文件大小(以字节为单位)
int xmlfilesize = 0;
// 初始化上传文件名称(完整文件名)
String xmlfilename = "";
// 声明文件存储字节数组
byte[] xmlfilebytes = null;
try {
// 初始化 SAX 串行xml文件解析器
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(request.getInputStream());
Element eroot = doc.getRootElement();

...

// 获取上传文件的大小
Iterator it_size = eroot.getChildren("uploadfilesize").iterator();
if (it_size.hasNext()) {
    xmlfilesize = Integer.parseInt(((Element) it_size.next()).getText());
    if (xmlfilesize > 0) {
        int unit_count = 0;
        // 为存储文件内容的字节数组分配存储空间
        xmlfilebytes = new byte[xmlfilesize];
        // 循环读取文件内容,并保存到字节数组中
        Iterator it_content = eroot.getChildren("uploadcontent").iterator();
        while (it_content.hasNext()) {
    // 初始化Base64编码解码器
        BASE64Decoder base64 = new BASE64Decoder();
        byte[] xmlnodebytearray = base64.decodeBuffer(((Element) it_content.next()).getText());
        if (xmlnodebytearray.length >= unit_size) {
        // 读取一个完整数据单元的数据
        System.arraycopy(xmlnodebytearray, 0, xmlfilebytes, unit_count * unit_size, unit_size);
        } else {
        // 读取小于一个数据单元的所有数据
        System.arraycopy(xmlnodebytearray, 0, xmlfilebytes, unit_count * unit_size,
            xmlfilesize % unit_size);
        }
        // 继续向下读取文件内容
    unit_count++;
    }
    }
}
InputStream input = new ByteArrayInputStream(xmlfilebytes);

这样一来便获取到了数据流,然后就可以为所欲为了吧

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值