1

Тема: HTA, JS: Как обрабатывать события ActiveX | COM объекта

Привет всем!
Давайте рассмотрим практическую задачу
решение которой надеюсь вы мне подскажите

Сразу скажу WSH не хочу юзать так как нет возможности создать нормальный  пользовательский интерфейс :)
Так же не хочу юзать XmlHttpRequest так как он не дает доступа к кукам и не дает возможности использовать прокси серверы :)

Задача получить страничку по http протоколу  Асинхронным методом //что бы потом можно было извлечь кукис из заголовков и получить код ответа сервера

Сначала сделаем это синхроным методом что бы удостоверится что нашь ActiveXObject на что-то способен

рабочий код

function hGET(url,func)
{
var R= new ActiveXObject("WinHttp.WinHttpRequest.5.1")
R.Open("GET",url,false)
R.Send()
func(R.ResponseText)
}

hGET("http://forum.script-coding.com/",function(a){
    document.body.innerText=a
})

А терь пробуем тоже самое асинхронным методом
НЕ рабочий код

function hGET(url,func)
{
var R= new ActiveXObject("WinHttp.WinHttpRequest.5.1")
R.Open("GET",url,true)
R.OnResponseDataAvailable=func //вот тут ослик вызовет ошибку
R.Send()

}

hGET("http://forum.script-coding.com/",function(a){
    document.body.innerText=a
})

Что делать как быть?:)

2

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

OnResponseDataAvailable - это событие, "приравнять" function к нему нельзя.
Попробуйте MSXML2.XMLHTTP. У него есть свойство onreadystatechange, которое в качестве аргумента может принимать function.

3

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

matiz, доступа к кукам он не дает

4 (изменено: mikser, 2011-03-12 22:44:57)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

омг даже на WSH не работает обработка событий

Вываливается с ошибкой!

var f=true;
function myReq_OnResponseFinished(a)
{
       f=false;
}

var myReq;
myReq=WScript.CreateObject("WinHttp.WinHttpRequest.5.1","myReq_");
myReq.Open("GET","http://forum.script-coding.com/",true);
myReq.Send();

while(f)WScript.Sleep(10);
WScript.Echo("Done");

почему?

5

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

может надо багрепорт слать мелгомяким?

6 (изменено: Xameleon, 2011-03-13 02:38:47)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

Вставлю свои 5 копеек. )

1) Я тоже пробывал повесить обработчик событий на WinHttp. У него неверно описаны события (для скриптового движка), из-за этого подключение к его событиям вызывает ошибку. Возможно ошибаюсь, т.к до конца не выяснял, но вроде бы проблема в типе данных, которые передаёт объект в связанные события. Такой "косяк" встречается у многих объектов. К примеру у той же коллекции ShellWindows. Ошибку не генерит, но и события не цепляет. Пробывал даже цеплять через коннектор событий в WSC. Теже грабли. Хотя в VBA и VB6 всё срабатывает без проблем.

2) 2 mikser:

matiz, доступа к кукам он не дает

А как Вы пробывали получить куки ?
На сколько я помню через XmlHttpRequest.GetResponseHeader("Set-Cookie") их можно было получить ? Ошибаюсь ?

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

7

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

2 Xameleon
"...Возможно Вам будет интересно ознакомиться с опытом одного исследователя, который так же безуспешно пытался подключить события от Excel http://www.dailydoseofexcel.com/archive … ntsor-not/ ..." - из одного моего обсуждения на этом форуме http://rastrwin.ru/support/forum/read.p … mp;TID=309.

8 (изменено: mikser, 2011-03-13 12:41:45)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

На сколько я помню через XmlHttpRequest.GetResponseHeader("Set-Cookie") их можно было получить ? Ошибаюсь ?

Можно но не все так просто.
Во первых  есть куки с флагом httponly IE помоему их не показывает скриптам даже в XmlHttpRequest.getResponseHeader
Во вторых давайте расмотрим как эту будет работать на практике
Вы отправляете на на сайт форму с логином и паролем
сервер отвечает кодом 302 ставит куки и делает редирект (location: урл)
браузера переадресовывает на страничку с контентом но уже почти (тока PHPSESSID) без куков в заголовке и вот ее как раз и выдает XmlHttpRequest.

Вот вам рабочий пример (тока что написал)
скрипт входит на почту квипа (Кстати утанавливать свои Cookie в запросе тоже не  получилось у меня)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <title>Mail Qip Enterer</title>
 </head>
 <body>
<script type="text/javascript">

function getTXT(h)
{
return h?h.replace(/<script[^>]*>[\W\w]*?<\/script>/gi,"").replace(/<style[^>]*>[\W\w]*?<\/style>/gi,"").replace(/[\n\r]+/g," ").replace(/<\/?(div|[tb]r)>/gi,"\n").replace(/<[^>]*>/g,"").replace(/&nbsp;/g," ").replace(/\n/gi,"<br>")/*.replace(/</g,"&lt;")*/:" null ";
}
//---------------------------------------------------------

function hPOST(url,dat,hHeads,func)
{
    var R=new ActiveXObject("MSXML2.XMLHTTP.3.0")
    R.Open("POST",url,true)
    for(var i=0;i<hHeads.length;i++)
    {
        var NameVal=hHeads[i].split(": ");
        //alert(NameVal)
        R.setRequestHeader(NameVal[0], NameVal[1])
    }
    R.setRequestHeader("Cookie","aaa=bbb")//
    R.setRequestHeader("Cookie","a1234=324")//куки кстати  не ставятся

    R.setRequestHeader("Content-Length", dat.length)
    R.onreadystatechange=function(b)
    {
        if(R.readyState==4)
            {
                func("Код Ответа: "+R.status+"<br>"+
                R.getAllResponseHeaders().split("\n").join("<br>")+"<hr>"+
                R.responseText)
                //func(R.responseText)
            }

    }
    R.Send(dat)
}//func

var hHeaders=[
"User-Agent: Opera/9.80 (Windows NT 6.1; U; googlebot/2.1; ru) Presto/2.7.39 Version/11.00",
"Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif: image/x-xbitmap, */*;q=0.1",
"Accept-Language: ru,en;q=0.9,ru-RU;q=0.8",
"Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1",
"Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0",
"Referer: http://mail.qip.ru/",
"Connection: Keep-Alive, TE",
"TE: deflate, gzip, chunked, identity, trailers",
"Content-Type: application/x-www-form-urlencoded"
];
var auth="user=sftest&dom=qip.ru&domain=qip.ru&reason=login&pass=asdasd";

hPOST("http://mail.qip.ru/auth/logon",auth, hHeaders,function(a)
    {
    document.body.innerHTML+=getTXT(a)
    })

  </script>
 </body>
</html>

9 (изменено: mikser, 2011-03-13 14:11:08)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

Вот как будет выглядеть этот диалог через снифер.
Вроде бы запрос всего 1 значит должен быть 1 запрос и 1 ответ но на самом деле.

User Agent:

POST /auth/logon HTTP/1.1
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Cookie: lastlogin=sftest%40qip.ru; rb_shows=1111%1115; rb_shows_day=1111-1%1115-1; PHPSESSID=08cb5fff420c525b7df74df221fc96df; autologin=%7B%22login%22%3A%22sftest%40qip.ru%22%2C%22hash%22%3A%22543f8faa349d1459753773a98cf2efdf%22%7D
te: deflate, gzip, chunked, identity, trailers
Connection: Keep-Alive, TE
User-Agent: Opera/9.80 (Windows NT 6.1; U; googlebot/2.1; ru) Presto/2.7.39 Version/11.00
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif
Content-Type: application/x-www-form-urlencoded
Accept-Language: ru,en;q=0.9,ru-RU;q=0.8
Accept-Encoding: gzip, deflate
Host: mail.qip.ru
Content-Length: 61
Cache-Control: no-cache

user=sftest&dom=qip.ru&domain=qip.ru&reason=login&pass=asdasd

Вот они куки где //но XHR их не видит этот заголовок
Server

HTTP/1.1 302 Found
Server: nginx/0.8.53
Date: Sun, 13 Mar 2011 08:23:38 GMT
Content-Type: text/html
Connection: close
X-Powered-By: qip.mail/4.1.21203 28.01.2011
Set-Cookie: PHPSESSID=08cb5fff420c525b7df74df221fc96df; path=/; domain=.qip.ru
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: arch_session=deleted; expires=Sat, 13-Mar-2010 08:23:37 GMT; path=/; httponly
Set-Cookie: PHPSESSID=67b0721e2eef44f6748d8133a21695fe; path=/; domain=.qip.ru
Set-Cookie: autologin=%7B%22login%22%3A%22sftest%40qip.ru%22%2C%22hash%22%3A%22543f8faa349d1459753773a98cf2efdf%22%7D; expires=Tue, 12-Apr-2011 08:23:38 GMT; path=/; domain=.qip.ru
Set-Cookie: lastlogin=sftest%40qip.ru; expires=Tue, 12-Apr-2011 08:23:38 GMT; path=/; domain=.qip.ru
Set-Cookie: PHPSESSID=c028cc0e6d13003cd5ed14e1b01f8e08; path=/; domain=.qip.ru
Set-Cookie: autologin=%7B%22login%22%3A%22sftest%40qip.ru%22%2C%22hash%22%3A%22543f8faa349d1459753773a98cf2efdf%22%7D; expires=Tue, 12-Apr-2011 08:23:38 GMT; path=/; domain=.qip.ru
Set-Cookie: lastlogin=sftest%40qip.ru; expires=Tue, 12-Apr-2011 08:23:38 GMT; path=/; domain=.qip.ru
Set-Cookie: PHPSESSID=67b0721e2eef44f6748d8133a21695fe; path=/; domain=.qip.ru
location: /~Inbox;
Content-Length: 0

Откуда взялся этот запрос я же его не делал! Что за самодеятельность???
User Agent:

GET /~Inbox; HTTP/1.1
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Cookie: lastlogin=sftest%40qip.ru; rb_shows=1111%1115; rb_shows_day=1111-1%1115-1; PHPSESSID=67b0721e2eef44f6748d8133a21695fe; autologin=%7B%22login%22%3A%22sftest%40qip.ru%22%2C%22hash%22%3A%22543f8faa349d1459753773a98cf2efdf%22%7D
te: deflate, gzip, chunked, identity, trailers
Connection: Keep-Alive, TE
User-Agent: Opera/9.80 (Windows NT 6.1; U; googlebot/2.1; ru) Presto/2.7.39 Version/11.00
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif
Content-Type: application/x-www-form-urlencoded
Accept-Language: ru,en;q=0.9,ru-RU;q=0.8
Accept-Encoding: gzip, deflate
Host: mail.qip.ru

Вот этот ответ Ослик показывает XHR
Server

HTTP/1.1 200 OK
Server: nginx/0.8.53
Date: Sun, 13 Mar 2011 08:23:38 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: close
X-Powered-By: qip.mail/4.1.21203 28.01.2011
Set-Cookie: PHPSESSID=67b0721e2eef44f6748d8133a21695fe; path=/; domain=.qip.ru
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Cache-Control: post-check=0, pre-check=0
Pragma: no-cache
Content-Encoding: gzip

<!DOCTYPE html>

тут контент странички
..

Ужс! Куки нельзя ни установить ни считать!
Что делать?

10 (изменено: Xameleon, 2011-03-13 13:50:03)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

http://support.microsoft.com/kb/234486/ru

Микрософт тут вот что говорит... )

Чтобы добавить файлы «cookie» на запрос вызова setRequestHeader для файла Cookie заголовка должна быть повторена, так как при первом вызове игнорируется.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

11 (изменено: mikser, 2011-03-13 14:06:18)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

Xameleon

Вот как выгдит вашь запрос через снифер - нету там куков

POST /auth/logon HTTP/1.1
Accept: */*
Accept-Language: ru
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; WebMoney Advisor; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; FDM)
Host: mail.qip.ru
Content-Length: 0
Connection: Keep-Alive
Cache-Control: no-cache

куки не отсылаются

Статью мс эту я уже давно читал -  Как видите  не правда это все

А то что вы заходите  - все дело в том что ие сохранил куки которые получил  когда вы запустили мой пример (почистите куки в ие)
Кстати вы в неправильном формате куки ставите хотя это наверно не важно

12

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

2 mikser: Как раз это и понял, поэтому свой код убрал. ) Сейчас дальше ковыряюсь.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

13 (изменено: mikser, 2011-03-13 15:40:25)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

Вот как проблема с редиректом решается если юзать WinHttp:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <title>Mail Qip Enterer</title>
 </head>
 <body>
<script type="text/javascript">

function getTXT(h)
{
return h?h.replace(/<script[^>]*>[\W\w]*?<\/script>/gi,"").replace(/<style[^>]*>[\W\w]*?<\/style>/gi,"").replace(/[\n\r]+/g," ").replace(/<\/?(div|[tb]r)>/gi,"\n").replace(/<[^>]*>/g,"").replace(/&nbsp;/g," ").replace(/\n/gi,"<br>")/*.replace(/</g,"&lt;")*/:" null ";
}
//---------------------------------------------------------
  var
  WinHttpRequestOption_UserAgentString=0,
  WinHttpRequestOption_URL=1,
  WinHttpRequestOption_URLCodePage=2,
  WinHttpRequestOption_EscapePercentInURL=3,
  WinHttpRequestOption_SslErrorIgnoreFlags=4,
  WinHttpRequestOption_SelectCertificate=5,
  WinHttpRequestOption_EnableRedirects=6,
  WinHttpRequestOption_UrlEscapeDisable=7,
  WinHttpRequestOption_UrlEscapeDisableQuery=8,
  WinHttpRequestOption_SecureProtocols=9,
  WinHttpRequestOption_EnableTracing=10,
  WinHttpRequestOption_RevertImpersonationOverSsl=11,
  WinHttpRequestOption_EnableHttpsToHttpRedirects=12,
  WinHttpRequestOption_EnablePassportAuthentication=13,
  WinHttpRequestOption_MaxAutomaticRedirects=14,
  WinHttpRequestOption_MaxResponseHeaderSize=15,
  WinHttpRequestOption_MaxResponseDrainSize=16,
  WinHttpRequestOption_EnableHttp1_1=17,
  WinHttpRequestOption_EnableCertificateRevocationCheck=18; 

function hPOST(url,dat,hHeads,func)
{
    var R=new ActiveXObject("WinHttp.WinHttpRequest.5.1")
    
    R.Open("POST",url,false)//R.Open("POST",url,false)
    for(var i=0;i<hHeads.length;i++)
    {
        var NameVal=hHeads[i].split(": ");
        //alert(NameVal)
        R.SetRequestHeader(NameVal[0], NameVal[1])
    }
    R.SetRequestHeader("Cookie","aaaa=bbbb")//
    R.SetRequestHeader("Cookie","EEE=GGG")//
    R.SetRequestHeader("Cookie","ccc=7777")//куки ставятся
    R.Option(WinHttpRequestOption_EnableRedirects)=0;
    R.SetRequestHeader("Content-Length", dat.length)
    R.Send(dat)
    func(       "Код Ответа: "+R.Status+"<br>"+
               R.GetAllResponseHeaders().split("\n").join("<br>")+"<hr>"+
               R.ResponseText
        )
}//func

var hHeaders=[
"User-Agent: Opera/9.80 (Windows NT 6.1; U; googlebot/2.1; ru) Presto/2.7.39 Version/11.00",
"Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif: image/x-xbitmap, */*;q=0.1",
"Accept-Language: ru,en;q=0.9,ru-RU;q=0.8",
"Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1",
//"Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0",
"Referer: http://mail.qip.ru/",
"Connection: Keep-Alive, TE",
"TE: deflate, gzip, chunked, identity, trailers",
"Content-Type: application/x-www-form-urlencoded"
];
var auth="user=sftest&dom=qip.ru&domain=qip.ru&reason=login&pass=asdasd";

hPOST("http://mail.qip.ru/auth/logon",auth, hHeaders,function(a)
    {
    document.body.innerHTML+=getTXT(a)

    })

  </script>
 </body>
</html>

Но это синхроный метод, мне нужен асинхроный  так как с синхроным методом ослик зависает иногда.

14

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

mikser, используйте знаки препинания.

15

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

to mikser:
Браузер и MSXML2.XMLHTTP (и подобные ему) "работают" по разному.
Если в http-ответе будет заголовок Set-Cookie, то браузер сохранит куки на клиенте для определенного хоста с временем их существования. Если браузер делает http-запрос, то в сохраненных куках ищет куки для запрашиваемого хоста и если срок их существования не истек, то вставляет в http-запрос заголовки Cookie.
MSXML2.XMLHTTP так делать автоматически "не умеет". Надо самому "беспокоиться" о наличии необходимых http-заголовков.

16 (изменено: mikser, 2011-03-13 19:38:18)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

alexii пишет:

mikser, используйте знаки препинания.

Ок, впредь буду стараться.

matiz пишет:

to mikser:
Браузер и MSXML2.XMLHTTP (и подобные ему) "работают" по разному.

Я тоже так думал.

matiz пишет:

Если в http-ответе будет заголовок Set-Cookie, то браузер сохранит куки на клиенте для определенного хоста с временем их существования. Если браузер делает http-запрос, то в сохраненных куках ищет куки для запрашиваемого хоста и если срок их существования не истек, то вставляет в http-запрос заголовки Cookie.

Истину глаголите.

matiz пишет:

MSXML2.XMLHTTP так делать автоматически "не умеет". Надо самому "беспокоиться" о наличии необходимых http-заголовков.

И я так полагал. А на практике он именно так и делает.
На самом деле MSXML2.XMLHTTP  не даст вам возможности ставить куки и читать их тоже не всегда возможно (В случае с редиректом).
Примеры изложенные мной выше это наглядно демонстрируют, сохраните их в файл запустите и сами все поймете.

Хьюстон, у нас проблемы!

17 (изменено: mikser, 2011-03-13 22:43:49)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

Как с помощью WMI  подписаться на событие OnResponseDataAvailable объекта  WinHttp.WinHttpRequest.5.1?

18

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

По-моему, никак. Подписываться можно только на собственные события WMI.

19

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

Странно особенно если учесть, что мс стока сил вложила стандартизацию COM объектов.

20 (изменено: Xameleon, 2011-03-14 13:31:28)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

Доброго времени суток. Сегодня в голову пришла следующая мысль - ну чёрт с ними с событяими, главное получить асинхронность. В черноте собрал код. На сколько я понял, задача - позволить запросу выполняться отдельно, не мешая основному коду продолжать работать. Я решил, что для этого вполне подойдёт SetTimeOut, который можно повесить на процедуры VBS. В принципе, если такой код устроит, то его легко перегнать на JS. Либо загнать в WSC и оформить как отдельный компонент с событиями. Если потребуется - готов даже сам собрать. )

Dim document, window, timerID, WinHttpRequest, ResponseFinished
Set document = CreateObject("htmlfile")
Set window = document.parentWindow
Set WinHttpRequest = CreateObject("WinHttp.WinHttpRequest.5.1")

WinHttpRequest.Open "GET","http://www.ya.ru",true
WinHttpRequest.Send
timerID = window.setInterval(getRef("WinHttpRequest_WaitForResponse"),1)

MsgBox "Метод Send вызван асинхронно. Это сообщение сгенерированно после него.",vbInformation

Do While Not ResponseFinished = True
    WScript.Sleep 100
Loop

Sub WinHttpRequest_WaitForResponse()
    if WinHttpRequest.WaitForResponse(1) = True Then 
        window.ClearInterval timerID
        WinHttpRequest_OnResponseFinished()
    End if
End Sub

Sub WinHttpRequest_OnResponseFinished()
    MsgBox "WinHttpRequest_OnResponseFinished"
    ResponseFinished = True
End Sub

P.S В принципе можно обойтись обычным Do Loop в котором ждать когда WaitForResponse(1) вернёт True, но при этом основной поток кода будет занят именно этой обработкой цикла.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

21 (изменено: Xameleon, 2011-03-14 15:31:30)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

Решил сразу собрать, чтоб было понятно о чём я.
Добавил HttpAsyncRequest.OnResponseFinished, к которому можно "аттачить" нужные процедуры.

Пока код избыточен. И наверняка можно обойтись без wsc, а собрать какую нибудь процедурку в скрипте, но я в черновом варианте решил так. Как JSman в тему заглянет - он наверное всё перекроит на JS ))). Пока в моём варианте WSC есть косяк - из-за использования VBS кода, нельзя делать опциональные параметры у методов объекта. На JS это решаемо.

Request.vbs

Set HttpAsyncRequest = GetObject("script:" & GetScriptPath & "HttpAsyncRequest.wsc")

HttpAsyncRequest.Open "GET","http://www.goole.ru"
Set HttpAsyncRequest.OnResponseFinished = GetRef("OnResponseFinished")
HttpAsyncRequest.Send ""

MsgBox "Waiting for response..."

Sub OnResponseFinished()
    MsgBox "OnResponseFinished"
End Sub

Function GetScriptPath()
    GetScriptPath = Left(WScript.ScriptFullName,InstrRev(WScript.ScriptFullName,"\"))
End Function

HttpAsyncRequest.wsc

<?xml version="1.0"?>
<component>
<?component error="true" debug="true"?>
<registration
    description="HttpAsyncRequest"
    progid="HttpAsyncRequest.wsc"
    version="1.00"
    classid="{cc8fb035-d00f-46ab-8680-9ef238da21a8}"
>
</registration>
<reference object="WinHttp.WinHttpRequest.5.1"/>
<object id="WinHttpRequest" progid="WinHttp.WinHttpRequest.5.1" events="True" />
<public>
    <property name="OnResponseFinished">
        <put/>
    </property>
    <property name="ResponseText">
        <get/>
    </property>
    <method name="Open">
        <PARAMETER name="Method"/>
        <PARAMETER name="Url"/>
    </method>
    <method name="SetRequestHeader">
        <PARAMETER name="Header"/>
        <PARAMETER name="Value"/>
    </method>
    <method name="GetResponseHeader">
        <PARAMETER name="Header"/>
    </method>
    <method name="Send"/>
</public>

<script language="VBScript">
<![CDATA[
Dim document, window, timerID, OnResponseFinished
Set document = CreateObject("htmlfile")
set window = document.parentWindow

function Open(Method,Url)
    WinHttpRequest.Abort
    WinHttpRequest.Open Method,Url,True
end function

function SetRequestHeader(Header,Value)
    WinHttpRequest.SetRequestHeader Header, Value
end function

function Send(Body)
    WinHttpRequest.Send Body
    window.ClearInterval timerID
    timerID = window.setInterval(getRef("WinHttpRequest_WaitForResponse"),1)
end function

function put_OnResponseFinished(Value)
    Set OnResponseFinished = Value
end function

function GetResponseHeader(Header)
    GetResponseHeader = WinHttpRequest.GetResponseHeader(Header)
end function

function WinHttpRequest_WaitForResponse()
    if WinHttpRequest.WaitForResponse(1) = True Then 
        window.ClearInterval(timerID)
        On Error Resume Next
        OnResponseFinished      
        On Error Goto 0
    End if
end function

function get_ResponseText()
    get_ResponseText = WinHttpRequest.ResponseText
end function

function get_ResponseBody()
    get_ResponseText = WinHttpRequest.ResponseBody
end function

]]>
</script>

</component>
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

22 (изменено: Xameleon, 2011-03-14 18:35:11)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

Либо третий вариант, с классом таймера. Возможно наиболее изящный.

Option Explicit

Dim WinHttpRequest, TimerGenerator, timerID
Set WinHttpRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
Set TimerGenerator = New clsTimerGenerator

WinHttpRequest.Open "GET","http://forum.script-coding.info", true
WinHttpRequest.Send
timerID = TimerGenerator.CreateTimer(getRef("WinHttpRequest_WaitForResponse"),1)

MsgBox "Ожидаем получение данных от сервера. Не закрывайте сообщение."

Sub WinHttpRequest_WaitForResponse()
    if WinHttpRequest.WaitForResponse(0) Then
        MsgBox "Данные получены !"
        MsgBox WinHttpRequest.responseText
        TimerGenerator.DestroyTimer timerID
    End if
End Sub
    
Class clsTimerGenerator
    Private document, window, timerID

    Private Sub Class_Initialize()
        set document = CreateObject("htmlfile")
        set window = document.parentWindow
    End Sub
    
    function CreateTimer(EventHandler,interval)
        CreateTimer = window.setInterval(EventHandler,interval)
    End function
    
    Sub DestroyTimer(timerID)
        window.ClearInterval timerID
    End Sub
End Class

Вот только сомневаюсь, как лучше - WinHttpRequest.WaitForResponse(1) или WinHttpRequest.WaitForResponse(0) ? В MSDN написано, что timeout указывается в секундах. Если он не указан, то ожидание длится до прихода ответа. Если указан, то вываливается по истечению срока. Интересно. А если я опрашиваю с нулевым таймаутом, то он интерпретируется как не указанный или как с нулевым ожиданием ? Надо потестить.....

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

23

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

Приветствую! Как вариант можно вот так оформить код:

function ProcessRequest(WinHttpReq, callback)
{
    var window = new ActiveXObject("HTMLFile").parentWindow;
    window.document.close();

    var Interval = window.setInterval(function () {if (WinHttpReq.WaitForResponse(1)) {window.clearInterval(Interval); callback(WinHttpReq);}}, 200)
}

function callback(WinHttpReq)
{
    WScript.Echo(WinHttpReq.ResponseText);
    WScript.Quit();
}

    var WinHttpReq = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
    WinHttpReq.Open("GET", "http://www.microsoft.com", true);
    WinHttpReq.Send();

    ProcessRequest(WinHttpReq, callback);

while (1) {WScript.Sleep(100);}

24 (изменено: mikser, 2011-03-15 10:14:06)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

JSman, Xameleon, Спасибо вам, вроде то что нужно!
Не заметил  в доках, что WaitForResponse может не только тупо ждать окончания запроса, потому сам не допёр до такого решения.

25 (изменено: NikR, 2011-03-15 15:56:25)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

Так же не хочу юзать XmlHttpRequest так как он не дает доступа к кукам и не дает возможности использовать прокси серверы

Используйте Msxml2.ServerXMLHTTP. Там и setProxy(2,'http://127.0.0.1:8888') есть, и заголовок с куки посмотреть можно через getAllResponseHeaders()

Кроме того, все куки, присланные внутри сессии отсылаются обратно, как полагается (и в Msxml2.XMLHTTP тоже).

26 (изменено: mikser, 2011-03-16 13:37:47)

Re: HTA, JS: Как обрабатывать события ActiveX | COM объекта

NikR пишет:

Так же не хочу юзать XmlHttpRequest так как он не дает доступа к кукам и не дает возможности использовать прокси серверы

Используйте Msxml2.ServerXMLHTTP. Там и setProxy(2,'http://127.0.0.1:8888') есть, и заголовок с куки посмотреть можно через getAllResponseHeaders()

Кроме того, все куки, присланные внутри сессии отсылаются обратно, как полагается (и в Msxml2.XMLHTTP тоже).

Спасибо, интересный объект не знал про него.
Но насколько я понял, посмотрев мсдн, в нем нельзя запретить редиректы, а я хочу контролировать http сессию даже свой куки менеджер написал на JS
В Msxml2.ServerXMLHTTP  мало настроек

setOption
Sets one of the following options:
SXH_OPTION_URL_CODEPAGE
SXH_OPTION_ESCAPE_PERCENT_IN_URL
SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS
SXH_OPTION_SELECT_CLIENT_SSL_CERT

сравните с количеством настроек в WinHttpRequest

typedef enum WinHttpRequestOption {
  WinHttpRequestOption_UserAgentString,
  WinHttpRequestOption_URL,
  WinHttpRequestOption_URLCodePage,
  WinHttpRequestOption_EscapePercentInURL,
  WinHttpRequestOption_SslErrorIgnoreFlags,
  WinHttpRequestOption_SelectCertificate,
  WinHttpRequestOption_EnableRedirects,
  WinHttpRequestOption_UrlEscapeDisable,
  WinHttpRequestOption_UrlEscapeDisableQuery,
  WinHttpRequestOption_SecureProtocols,
  WinHttpRequestOption_EnableTracing,
  WinHttpRequestOption_RevertImpersonationOverSsl,
  WinHttpRequestOption_EnableHttpsToHttpRedirects,
  WinHttpRequestOption_EnablePassportAuthentication,
  WinHttpRequestOption_MaxAutomaticRedirects,
  WinHttpRequestOption_MaxResponseHeaderSize,
  WinHttpRequestOption_MaxResponseDrainSize,
  WinHttpRequestOption_EnableHttp1_1,
  WinHttpRequestOption_EnableCertificateRevocationCheck
} WinHttpRequestOption;