papapa314 发表于 2010-12-29 16:58:07

如何用winhttp UDF上传邮箱附件?

用ControlSetText给对话框输入一个文件路径的方法我已经会了。但我想做个后台的,在搜索论坛的时候从坛友的只言片语中得知可以使用winhttp udf。我看了一个下午的winhttp udf,却没找到一个好的例子。不知道谁能够给一个例子呀,比如网易邮箱自动上传指定路径的附件?万谢!

republican 发表于 2010-12-29 17:11:39

本帖最后由 republican 于 2010-12-31 07:12 编辑

回复 1# papapa314

除了参考我的内容外,你还可以参考_WinHttpSimpleXXX(真的忘了,也没怎么仔细看过)

以下所有内容均以HFS作为服务端。

表单内容:POST /360Downloads/ HTTP/1.1
Accept: application/x-shockwave-flash, image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
Referer: http://10.17.133.128:82/360Downloads/~upload
Accept-Language: zh-cn
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Content-Type: multipart/form-data; boundary=---------------------------7da9c21d0988
Accept-Encoding: gzip, deflate
Host: 10.17.133.128:82
Content-Length: 624698
Connection: Keep-Alive
Cache-Control: no-cache

-----------------------------7da9c21d0988
Content-Disposition: form-data; name="fileupload1"; filename="名称."
Content-Type: application/octet-stream
数据段...

-----------------------------7da9c21d0988
Content-Disposition: form-data; name="fileupload2"; filename=""
Content-Type: application/octet-stream


-----------------------------7da9c21d0988
Content-Disposition: form-data; name="fileupload3"; filename=""
Content-Type: application/octet-stream


-----------------------------7da9c21d0988
Content-Disposition: form-data; name="fileupload4"; filename=""
Content-Type: application/octet-stream


-----------------------------7da9c21d0988
Content-Disposition: form-data; name="fileupload5"; filename=""
Content-Type: application/octet-stream


-----------------------------7da9c21d0988
Content-Disposition: form-data; name="fileupload6"; filename=""
Content-Type: application/octet-stream


-----------------------------7da9c21d0988
Content-Disposition: form-data; name="fileupload7"; filename=""
Content-Type: application/octet-stream


-----------------------------7da9c21d0988
Content-Disposition: form-data; name="fileupload8"; filename=""
Content-Type: application/octet-stream


-----------------------------7da9c21d0988
Content-Disposition: form-data; name="fileupload9"; filename=""
Content-Type: application/octet-stream


-----------------------------7da9c21d0988
Content-Disposition: form-data; name="fileupload10"; filename=""
Content-Type: application/octet-stream


-----------------------------7da9c21d0988--根据上述内容,我们就可以这样编写代码:
;~ #include <WinhttpGetrespond.au3>
#include <Winhttp.au3>
;~ $StrBoundary=_IntBoundary()
#include <array.au3>
Local $FPath
$FPath =FileOpenDialog("请选择文件","F\","所有文件(*.*)")

$MyOpen = _WinHttpOpen()
$Result=_WinHTTP_POSTFile($MyOpen,"10.17.133.128","/360Downloads/",$FPath,"fileupload",4)
If @error Then MsgBox(0,"",@error)
MsgBox(0,5,$Result)
_WinHttpCloseHandle($MyOpen)

Func _WinHTTP_POSTFile($hOpen,$ServerHost,$URLObj,$FileArray,$IDName,$EndNum,$ReturnMode=0,$Cookies = "",$MoreHeader = "")
        If $hOpen = "" Or $ServerHost = "" Then Return SetError(1,0,-1)
        $hConnect=_WinHttpConnect($hOpen, $ServerHost,82)
        ;建立连接
        $hRequest = _WinHttpOpenRequest($hConnect, "POST", $URLObj)
        If @error Or $hRequest = 0Then Return SetError(1,0,-1)
        ;------------计算数据长度---------------
        $POSTDateLen = 0
        $POSTBasicLen=BinaryLen(StringToBinary(@CRLF&'-----------------------------012345678901'&@CRLF & _
                                                        'Content-Disposition: form-data; name="'&$IDName&'"; filename=""'&@CRLF & _
                                                        'Content-Type: application/octet-stream'&@CRLF&@CRLF))
        For $i = 1 To $EndNum
                $POSTDateLen += $POSTBasicLen + BinaryLen(String($i))
        Next
        $POSTDateLen +=47
        ;基本长度获取完毕
        For $i = 1 To UBound($FileArray)
                If FileExists($FileArray[$i -1 ]) Then $POSTDateLen +=FileGetSize($FileArray[$i -1 ]) + BinaryLen(StringToBinary($FileArray[$i -1]))                        ;添加文件及文件路径长度
        Next
        ;-------------------End of Lenth-----------------------------------
        $POSTBoundary=_IntBoundary()
       
        _WinHttpAddRequestHeaders($hRequest, "Content-Length: "&$POSTDateLen&@CRLF)
        _WinHttpAddRequestHeaders($hRequest, "Content-Type: multipart/form-data; boundary=---------------------------"&$POSTBoundary)
       
        _WinHttpSendRequest($hRequest)                ;发送请求
        ;--------------------------------发送数据----------------------------------------------
        For $i=1 To $EndNum
                If $i <=UBound($FileArray) And FileExists($FileArray[$i -1 ]) Then
                        ConsoleWrite($i&@CRLF)
                        $ContextDate =StringToBinary(@CRLF & '-----------------------------'&$POSTBoundary&@CRLF & _
                                                                                'Content-Disposition: form-data; name="'&$IDName&$I&'"; filename="'&$FileArray[$i -1]&'"'&@CRLF & _
                                                                                'Content-Type: application/octet-stream'&@CRLF&@CRLF)
                        _WinHttpWriteData($hRequest,$ContextDate,1)
                       
                        $hFile = FileOpen($FileArray[$i -1],16)
                        While 1
                                $dFile = FileRead($hFile,1024 * 512)
                                If @error Then ExitLoop
                                _WinHttpWriteData($hRequest,$dFile,1)
                                Sleep(10)
                        WEnd
                        FileClose($hFile)
                Else
                        $ContextDate =StringToBinary(@CRLF & '-----------------------------'&$POSTBoundary&@CRLF & _
                                                                                'Content-Disposition: form-data; name="'&$IDName&$I&'"; filename=""'&@CRLF & _
                                                                                'Content-Type: application/octet-stream'&@CRLF&@CRLF)
                        _WinHttpWriteData($hRequest,$ContextDate,1)
                EndIf
        Next
       
        $ContextDate =StringToBinary(@CRLF &'-----------------------------'&$POSTBoundary&'--'&@CRLF)
        _WinHttpWriteData($hRequest,$ContextDate,1)
       
;~         Sleep(200)
        _WinHttpReceiveResponse($hRequest)                ;获取回应
       
        If Not _WinHttpQueryDataAvailable($hRequest) Then Return SetError(4,0,-4)

        Local $iReturn = [-1,-1,-1,-1,-1,-1]
       
        $iReturn=_WinHttpQueryHeaders($hRequest,$WINHTTP_QUERY_STATUS_CODE)        ;服务器状态
        $iReturn=_WinHttpQueryHeaders($hRequest,$WINHTTP_QUERY_CONTENT_LENGTH)        ;文件长度
        $iReturn=_WinHttpQueryHeaders($hRequest,$WINHTTP_QUERY_SET_COOKIE)                ;首个Cookies
        $iReturn=_WinHttpQueryHeaders($hRequest,$WINHTTP_QUERY_LOCATION)                        ;重定向
        $iReturn=_WinHttpQueryHeaders($hRequest,$WINHTTP_QUERY_CONTENT_TYPE)                ;编码类型
        $iReturn= BinaryToString(_WinHttpReadData($hRequest,2,Int($iReturn)))
       
        _WinHttpCloseHandle($hRequest)
        _WinHttpCloseHandle($hConnect)
        Return $iReturn
EndFunc

Func _IntBoundary()
        Local $Letter,$Boundary="7f"
        For $i = 0 To 19
                If $i < 10 Then $Letter[$i] = Chr(Random(97, 122, 1))
                If $i >= 10 Then $Letter[$i]=Random(0,9,1)
        Next
        For $i = 0 To 9
                $Boundary &=$Letter
        Next
        Return $Boundary
EndFunc


POST FILE必需先研究对方的格式,再自己定义.

演示图:

papapa314 发表于 2010-12-29 18:39:14

好厉害,这么快就写出来了!我是新新手,学了第四天autoit了,看了一个下午的winhttp而已。先表示感谢,下载下来好好研究,如果还有问题,希望还能够向老大请教!!

hanqin 发表于 2010-12-30 13:15:11

顶上去!!!

auto 发表于 2011-1-1 11:40:08

高手啊,BBSXP论坛或DISCUZ论坛上传附件(如GIF\JPG\rar)如何后台发送

papapa314 发表于 2011-1-3 16:03:19

研究了很多天还是不懂呀,同5#问

lxz 发表于 2011-1-3 19:45:42

学习学习....

republican 发表于 2011-1-3 21:26:00

回复 6# papapa314

研究到什么程度了?

共享出来看看·~

papapa314 发表于 2011-1-12 22:59:36

回复 2# republican


这个研究了好久,还是不了解呀,对于新手而言,真的很难了解。能不能从基础点开始讲解呢,比如开头的那个代码是用什么工具抓包的,如果抓包的?

republican 发表于 2011-1-13 14:39:55

回复 9# papapa314
搜这个:
全自动后台投票机实例+分析教程
看到第四步就好了。

papapa314 发表于 2011-1-13 16:41:44

回复 10# republican

谢谢republican,已经学习到了,在实践中了!!等我会操作这个了,再来跟你进一步学习如何post上传,呵呵

papapa314 发表于 2011-1-13 20:48:30

本帖最后由 papapa314 于 2011-1-13 20:50 编辑

回复 10# republican

请问,运行了你的程序后msgbox提示4,这个是什么意思呢?

而且好像没有上传成功,如果上传成功后应该会提示什么信息呢?

republican 发表于 2011-1-13 22:04:02

If Not _WinHttpQueryDataAvailable($hRequest) Then Return SetError(4,0,-4)服务器无有效数据返回,这个一般是提交内容不符合要求所致。

你开了HFS了吗?

papapa314 发表于 2011-1-13 23:21:17

回复 13# republican


   HFS没有开呢,如果开了是不是比较麻烦呀,请问能不能不借助第三方的工具呢?

另外,很感谢你的帮助,我已经知道怎么获得你提供的那个表单内容了,表单的前半部分看得懂了,可后半部分的数据段还是看得糊里糊涂的,也不知道怎么使用这些数据段?

republican 发表于 2011-1-13 23:34:52

回复 14# papapa314

没开当然error 4啦,这个就是专门为HFS写的。
页: [1] 2
查看完整版本: 如何用winhttp UDF上传邮箱附件?