VBA http post 上传 multipart/form

生僻字1 2019-04-16 05:10178http://www.cdaxzc.comadmin

时 间:2012-12-15 07:10:00
作 者:dbaseIIIer   ID:22003  城市:深圳
摘 要:寻遍世界各个网站,各个关键字都没有的情况下,自己终于测试出来了!也回复了google上2006年以来发表都还没有解决的问题!
正 文:

上传附件,原来逻辑也很简单,但是因为中文的问题,unicode 的问题,让上传变得复杂了!


方法一:我们可以用 WebBrower 控件来处理网页的提交动作的。我们可以通过 WebBrowser.Document.form(n).submit() 来提交网页表单的内容。不过这个方法的缺点是:

1. 这个控件是IE提供的原因,就有着浏览器是IE对的限制,譬如 user-agent 就一定是 ie ,

2. 交互的服务器也只能是 html 的,不能是wap 服务器(ie 不支持 WML 标识);而且 

3. WebBrowser 控件的内存耗用也比较大,对于同时多开的操作,就会让程序变慢,内存耗用激增!


所以,我针对的研究是用 XMLHttp 直接与服务器交互的 方法二。

这个方法的好处是,原理通用于任何标准的 网页服务器,不论 IIS, Apache, tomcat,或不论服务器的开发语言是 jsp , php , asp, asp.net。 我们开发的客户端也可以是 js, Access/VBA, Excel/VBA, php ... 都能正确使用!


对于上传 multipart/form-data 格式的附件,找了很久找到很多段的代码,标准就是要输出这样的结果:

--boundary Content-Disposition: form-data;; <变量值> --boundary Content-Disposition: form-data;; filename="上传文件名称" Content-Type:<文件内容> --boundary--

看了下这个标准,会编程的人都会生成文本数据的了,不消一会就写好了,

Set http = New MSXML2.ServerXMLHTTP http.Open "POST", URL, False postData = ...... http.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & boundary http.setRequestHeader "Content-Length", len( postData) http.Send postData http.WaitForResponse Debug.Print http.responseText

可是问题出现了,怎么服务器没有响应我的提交有变量提交的呢?测试了 iis, apache 都是失败!


打开了 Chrome 浏览器,用网页打开,提交后,在调试页面看到提交的内容,跟我提交的内容都是一模一样的呢,怎么我用 xmlhttp 提交的就没有结果的呢?玩了几6个小时,左对右对,都没有答案!


第二天,安装了一个http封包截取器(fiddler 挺好用的!)看看我提交的跟 Chrome 提交的区别在哪里!发现了重大问题!


重点1:我们提交的 postData 文本,都是用程序生成的,原来没经过处理,就是 Unicode 文本!但是 multipart/form-data 的标准就不该是 unicode 文本!所以我们需要转义!


在生成的 postData 文本,用了一个 strConv( postData, vbFromUnicode),去测试,还是不行!玩来玩去,把附件去掉,服务器就对我的提交,终于感受到有变量了!但是显示结果怎么还是有问题的???又玩了一段时间,发现重点2了。


重点2:我们查看结果一般会用 http.responseText ,可是如果我们输出网页的内容包含中文字,这就牵涉 unicode 问题了!所以我们看结果需要用  StrConv(http.responseBody, vbUnicode)


现在变量可以顺利提交了,但是附件呢?还是不行,每次加上附件的那几行来提交就出错了!所以我就怀疑 StrConv 把 binary 的数据都改变了,我写了几句话去测试:


cFile = "e:\qq\0.jpg" Dim b() As Byte ReDim b(FileLen(cFile)) ff = FreeFile Open cFile For Binary As #ff Get #ff, , b Close #ff Dim s1 As String, s2 As String s1 = b s2 = StrConv(s1, vbUnicode) s2 = StrConv(s2, vbFromUnicode) Debug.Print Len(s1), Len(s2) 结果发现, StrConv 转换为 vbUnicode 然后又转回来的话,是不会一样的! 连长度都不一样,我就没有比较内容了!所以:



重点3: 千万不要让 StrConv 去处理 postData文本 中 附件的部分!


其实当中,我也花了不少时间去研究怎么把二进制数据与这个提交文本合并在一起的,其中我用了不同的方式来合并文本和二进制数据,不过经过测试后,也知道重点1 和 重点3 之后,就引刃而解了!


重点4:附件读入为文本,不能当字符串处理!


找到有一段错误的代码是


nFile = FreeFile Open strFileName For Binary As #nFile strFile = String(LOF(nFile), " ") Get #nFile, , strFile Close #nFile 看似很正确的做法,不过,其实对于不同年代的 Basic 语言来说曾经是正确的。因为现在是 Unicode 年代,用 String函数生成的 字符串都是 Unicode的,所以 String( LOF(nFile), " ") 会生成了比原来文件大了一倍的空间!因为Unicode的字符是双字节的,读入文件的大小是描述 Byte 的。根据这个方法读进来的数据,在没有 Unicode 年代的 VB, VBA, Basic 都是对的!



生僻字怎么读_大全:VBA http post 上传 multipart/form

Copyright © 2002-2019 生僻字怎么读_大全 版权所有 备案号: