Results 1 to 17 of 17

Thread: xmlhttp async problem

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Mar 2016
    Posts
    224

    xmlhttp async problem

    i am trying to make xmlhttp async and make some kind of state changed event but my code failed

    Sub HandleStateChange()

    If (myMSXML.readyState = 4) Then
    MsgBox myMSXML.responseText
    End If
    End Sub

    please help
    Last edited by geekmaro; Oct 25th, 2020 at 01:40 AM.

  2. #2
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: xmlhttp async problem

    A problem with MSXML is that the bonehead parts of it were optimized for use from JScript. As a result you have to simulate JScript event binding in VB6.

    Form1.frm
    Code:
    Option Explicit
    
    Private HTTP As MSXML2.XMLHTTP60
    Private WithEvents SinkRSChange As SinkRSChange
    
    Private Sub Form_Load()
        Set HTTP = New MSXML2.XMLHTTP60
        Set SinkRSChange = New SinkRSChange
    End Sub
    
    Private Sub Form_Resize()
        If WindowState <> vbMinimized Then
            Text1.Move 0, 0, ScaleWidth, ScaleHeight
        End If
    End Sub
    
    Private Sub mnuGo_Click()
        With HTTP
            .open "GET", "https://www.google.com/", True
            .onreadystatechange = SinkRSChange
            Text1.Text = "Starting async GET" & vbNewLine
            .send
        End With
    End Sub
    
    Private Sub SinkRSChange_onreadystatechange()
        With HTTP
            Text1.Text = Text1.Text & vbNewLine & "readyState = " & CStr(.readyState)
            If .readyState = 4 Then
                Text1.Text = Text1.Text _
                           & vbNewLine & vbNewLine _
                           & CStr(.Status) & " " & .statusText _
                           & vbNewLine & vbNewLine _
                           & .responseText
            End If
        End With
    End Sub
    SinkRSChange.cls
    Code:
    Option Explicit
    
    Public Event onreadystatechange()
    
    'Mark as default member via Tools|Procedure Attributes... dialog.
    Public Sub RSChange()
        RaiseEvent onreadystatechange
    End Sub

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Mar 2016
    Posts
    224

    Re: xmlhttp async problem

    Quote Originally Posted by dilettante View Post
    A problem with MSXML is that the bonehead parts of it were optimized for use from JScript. As a result you have to simulate JScript event binding in VB6.

    Form1.frm
    Code:
    Option Explicit
    
    Private HTTP As MSXML2.XMLHTTP60
    Private WithEvents SinkRSChange As SinkRSChange
    
    Private Sub Form_Load()
        Set HTTP = New MSXML2.XMLHTTP60
        Set SinkRSChange = New SinkRSChange
    End Sub
    
    Private Sub Form_Resize()
        If WindowState <> vbMinimized Then
            Text1.Move 0, 0, ScaleWidth, ScaleHeight
        End If
    End Sub
    
    Private Sub mnuGo_Click()
        With HTTP
            .open "GET", "https://www.google.com/", True
            .onreadystatechange = SinkRSChange
            Text1.Text = "Starting async GET" & vbNewLine
            .send
        End With
    End Sub
    
    Private Sub SinkRSChange_onreadystatechange()
        With HTTP
            Text1.Text = Text1.Text & vbNewLine & "readyState = " & CStr(.readyState)
            If .readyState = 4 Then
                Text1.Text = Text1.Text _
                           & vbNewLine & vbNewLine _
                           & CStr(.Status) & " " & .statusText _
                           & vbNewLine & vbNewLine _
                           & .responseText
            End If
        End With
    End Sub
    SinkRSChange.cls
    Code:
    Option Explicit
    
    Public Event onreadystatechange()
    
    'Mark as default member via Tools|Procedure Attributes... dialog.
    Public Sub RSChange()
        RaiseEvent onreadystatechange
    End Sub
    could you please send me the whole project in archive like zip
    because i tried your code and code error at line; WithEvents SinkRSChange As SinkRSChange, it shows user defined type not defined
    and also the procedure attribute part i dont know how to do it
    thanks alot

  4. #4
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: xmlhttp async problem

    I'm not sure that will help because you will have to set or verify the attribute in your own programs. Small edits can easily wipe it out.

    Did you create a class named SinkRSChange?
    Attached Files Attached Files

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Mar 2016
    Posts
    224

    Re: xmlhttp async problem

    Quote Originally Posted by dilettante View Post
    I'm not sure that will help because you will have to set or verify the attribute in your own programs. Small edits can easily wipe it out.

    Did you create a class named SinkRSChange?
    it works but i have just one problem with posting cookies:
    i tried this but didnt work

    .setRequestHeader "Cookie", "PHPSESSID=ane07viahn98n5xjagv777xx82; session=7723030430c4c6c52896479492e2e546e52189c6235412e4e3372737a4c382f542d4a6569614b7a7a774653667a4 c68694a766852456b685a2e6771586a634a7a7946486174382f2f455733754867714a6644425530"

    please help
    Last edited by geekmaro; Oct 25th, 2020 at 06:31 PM.

  6. #6
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,746

    Re: xmlhttp async problem

    you can use winhttprequest 5.1,so you you can remove xmlhttp object

  7. #7

    Thread Starter
    Addicted Member
    Join Date
    Mar 2016
    Posts
    224

    Re: xmlhttp async problem

    Quote Originally Posted by xiaoyao View Post
    you can use winhttprequest 5.1,so you you can remove xmlhttp object
    with winhttp i cant post cookies, my goal is to make a post request using cookies
    only with xmlhttp i was able to obtain cookies, now i just need to post them
    please help me
    thank you

  8. #8
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,746

    Re: xmlhttp async problem

    winhttp can use cookie

  9. #9

    Thread Starter
    Addicted Member
    Join Date
    Mar 2016
    Posts
    224

    Re: xmlhttp async problem

    Quote Originally Posted by xiaoyao View Post
    winhttp can use cookie
    i cant get cookies with it, i could only get first part of cookies, but not session id, and session is part of cookies

  10. #10
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,319

    Resolved Re: xmlhttp async problem

    Quote Originally Posted by dilettante View Post
    A problem with MSXML is that the bonehead parts of it were optimized for use from JScript. As a result you have to simulate JScript event binding in VB6.

    Form1.frm
    Code:
    Option Explicit
    
    Private HTTP As MSXML2.XMLHTTP60
    Private WithEvents SinkRSChange As SinkRSChange
    
    Private Sub Form_Load()
        Set HTTP = New MSXML2.XMLHTTP60
        Set SinkRSChange = New SinkRSChange
    End Sub
    
    Private Sub Form_Resize()
        If WindowState <> vbMinimized Then
            Text1.Move 0, 0, ScaleWidth, ScaleHeight
        End If
    End Sub
    
    Private Sub mnuGo_Click()
        With HTTP
            .open "GET", "https://www.google.com/", True
            .onreadystatechange = SinkRSChange
            Text1.Text = "Starting async GET" & vbNewLine
            .send
        End With
    End Sub
    
    Private Sub SinkRSChange_onreadystatechange()
        With HTTP
            Text1.Text = Text1.Text & vbNewLine & "readyState = " & CStr(.readyState)
            If .readyState = 4 Then
                Text1.Text = Text1.Text _
                           & vbNewLine & vbNewLine _
                           & CStr(.Status) & " " & .statusText _
                           & vbNewLine & vbNewLine _
                           & .responseText
            End If
        End With
    End Sub
    SinkRSChange.cls
    Code:
    Option Explicit
    
    Public Event onreadystatechange()
    
    'Mark as default member via Tools|Procedure Attributes... dialog.
    Public Sub RSChange()
        RaiseEvent onreadystatechange
    End Sub
    I have found your post while searching how to use the "OnReadyStateChange" property. However I wanted to start multiple HTTP requests asynchronously and this approach using "withevents" with a "wrapper" class doesn't allow for that. I have modified the code slightly and now it works with an array of HTTP objects and their corresponding array of "SinkRSChange" classes:

    frmRSChange.frm
    Code:
    Option Explicit
    
    Implements IRSSinkEvents
    
    Private HTTP() As MSXML2.XMLHTTP60, SinkRSChange() As clsSinkRSChange, sURL() As String
    
    Private Sub Form_Load()
    Dim i As Long
        ReDim HTTP(0 To 2): ReDim SinkRSChange(0 To 2): ReDim sURL(0 To 2)
        sURL(0) = "https://www.microsoft.com"
        sURL(1) = "https://www.apple.com"
        sURL(2) = "https://www.amazon.com"
        For i = LBound(HTTP) To UBound(HTTP)
            Set HTTP(i) = New MSXML2.XMLHTTP60
            Set SinkRSChange(i) = New clsSinkRSChange
            Set SinkRSChange(i).Callback(i) = Me
        Next i
    End Sub
    
    Private Sub Form_Resize()
        If WindowState <> vbMinimized Then
            txtRSChange.Move 0, 0, ScaleWidth, ScaleHeight
        End If
    End Sub
    
    Private Sub mnuGo_Click()
    Dim i As Long
        For i = LBound(HTTP) To UBound(HTTP)
            With HTTP(i)
                .open "GET", sURL(i), True
                .OnReadyStateChange = SinkRSChange(i)
                txtRSChange.Text = txtRSChange.Text & sURL(i) & " - starting async GET" & vbNewLine
                .send
            End With
        Next i
    End Sub
    
    Private Sub IRSSinkEvents_OnReadyStateChange(Index As Long)
        With HTTP(Index)
            txtRSChange.Text = txtRSChange.Text & vbNewLine & sURL(Index) & " - readyState = " & .readyState
            If .readyState = 4 Then
                txtRSChange.Text = txtRSChange.Text & vbNewLine & vbNewLine & .Status & " " & .statusText & vbNewLine & vbNewLine & Left$(.responseText, 2000)
            End If
        End With
    End Sub
    clsSinkRSChange.cls
    Code:
    Option Explicit
    
    Private m_Index As Long, m_Callback As IRSSinkEvents
    
    Public Property Get Callback(Optional Index As Long) As IRSSinkEvents
        Index = m_Index
        Set Callback = m_Callback
    End Property
    
    Public Property Set Callback(Index As Long, objCallback As IRSSinkEvents)
        m_Index = Index
        Set m_Callback = objCallback
    End Property
    
    Public Sub ReadyStateChange()
        If Not (m_Callback Is Nothing) Then m_Callback.OnReadyStateChange m_Index
    End Sub
    IRSSinkEvents.cls
    Code:
    Option Explicit
    
    Public Sub OnReadyStateChange(Index As Long)
    
    End Sub
    Now a single "OnReadyStateChange" event can report the state of many HTTP requests!

  11. #11
    Fanatic Member
    Join Date
    Aug 2016
    Posts
    673

  12. #12
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,319

    Re: xmlhttp async problem

    Hey mate, thanks for that link, I like that approach as well! I guess there is more than one way to skin a cat, haha! That code seems to be using "WinHttpRequest" which exposes its own events as opposed to the simpler "XMLHTTP60" which doesn't have any events and exposes only the crummy "OnReadyStateChange" property. To be honest I am on the fence which of these two methods is better... Are there any obvious advantages/disadvantages to either of them?

  13. #13
    Fanatic Member
    Join Date
    Aug 2016
    Posts
    673

    Re: xmlhttp async problem

    WinHttpRequest is better than XMLHTTP!

    Xmlhttp always displays cached pages when called multiple times

  14. #14
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: xmlhttp async problem

    Just found out how to "gut" WinHttpRequest internal HINTERNET handles so that these can be manipulated further with WinHttpSetOption API function, for instance allowing gzip decompression from response, etc.

    Code:
    Option Explicit
    
    Private Const WINHTTP_OPTION_HANDLE_TYPE                     As Long = 9
    
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    Private Declare Function WinHttpQueryOption Lib "WinHttp" (ByVal hInternet As Long, ByVal dwOption As Long, lpBuffer As Any, lpdwBufferLength As Long) As Long
    
    Private Sub Form_Load()
        Dim oHttp           As WinHttpRequest
        Dim hConnect        As Long
        Dim hRequest        As Long
        Dim hSession        As Long
        Dim lType           As Long
        
        Set oHttp = New WinHttpRequest
        oHttp.Open "GET", "https://vbforums.com"
        hConnect = Peek(ObjPtr(oHttp) + &H30)
        hRequest = Peek(ObjPtr(oHttp) + &H34)
        hSession = Peek(ObjPtr(oHttp) + &H38)
        If WinHttpQueryOption(hConnect, WINHTTP_OPTION_HANDLE_TYPE, lType, 4) <> 0 Then
            Debug.Print "hConnect=" & Hex$(hConnect), lType
        End If
        If WinHttpQueryOption(hRequest, WINHTTP_OPTION_HANDLE_TYPE, lType, 4) <> 0 Then
            Debug.Print "hRequest=" & Hex$(hRequest), lType
        End If
        If WinHttpQueryOption(hSession, WINHTTP_OPTION_HANDLE_TYPE, lType, 4) <> 0 Then
            Debug.Print "hSession=" & Hex$(hSession), lType
        End If
    End Sub
    
    Private Function Peek(ByVal lPtr As Long) As Long
        Call CopyMemory(Peek, ByVal lPtr, 4)
    End Function
    Check out the Option flags documentation for possible useful extra settings available which are not exposed by WinHttpRequest object's Option property.

    The offsets into the internal instance state -- &H30, &H34 and &H38 -- work on XP to Win11 so leaving this here for posterity. (Search these forums for "WinHttpQueryOption" or "WinHttpSetOption" keywords -- these API functions have never been mentioned here before apparently.)

    cheers,
    </wqw>

  15. #15
    Fanatic Member
    Join Date
    Aug 2016
    Posts
    673

    Re: xmlhttp async problem

    Quote Originally Posted by wqweto View Post
    Just found out how to "gut" WinHttpRequest internal HINTERNET handles so that these can be manipulated further with WinHttpSetOption API function, for instance allowing gzip decompression from response, etc.

    Code:
    Option Explicit
    
    Private Const WINHTTP_OPTION_HANDLE_TYPE                     As Long = 9
    
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    Private Declare Function WinHttpQueryOption Lib "WinHttp" (ByVal hInternet As Long, ByVal dwOption As Long, lpBuffer As Any, lpdwBufferLength As Long) As Long
    
    Private Sub Form_Load()
        Dim oHttp           As WinHttpRequest
        Dim hConnect        As Long
        Dim hRequest        As Long
        Dim hSession        As Long
        Dim lType           As Long
        
        Set oHttp = New WinHttpRequest
        oHttp.Open "GET", "https://vbforums.com"
        hConnect = Peek(ObjPtr(oHttp) + &H30)
        hRequest = Peek(ObjPtr(oHttp) + &H34)
        hSession = Peek(ObjPtr(oHttp) + &H38)
        If WinHttpQueryOption(hConnect, WINHTTP_OPTION_HANDLE_TYPE, lType, 4) <> 0 Then
            Debug.Print "hConnect=" & Hex$(hConnect), lType
        End If
        If WinHttpQueryOption(hRequest, WINHTTP_OPTION_HANDLE_TYPE, lType, 4) <> 0 Then
            Debug.Print "hRequest=" & Hex$(hRequest), lType
        End If
        If WinHttpQueryOption(hSession, WINHTTP_OPTION_HANDLE_TYPE, lType, 4) <> 0 Then
            Debug.Print "hSession=" & Hex$(hSession), lType
        End If
    End Sub
    
    Private Function Peek(ByVal lPtr As Long) As Long
        Call CopyMemory(Peek, ByVal lPtr, 4)
    End Function
    Check out the Option flags documentation for possible useful extra settings available which are not exposed by WinHttpRequest object's Option property.

    The offsets into the internal instance state -- &H30, &H34 and &H38 -- work on XP to Win11 so leaving this here for posterity. (Search these forums for "WinHttpQueryOption" or "WinHttpSetOption" keywords -- these API functions have never been mentioned here before apparently.)

    cheers,
    </wqw>
    Is there any difference between api Winhttpsetoption and winhttp.Option

  16. #16
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: xmlhttp async problem

    Quote Originally Posted by xxdoc123 View Post
    Is there any difference between api Winhttpsetoption and winhttp.Option
    winhttp.Option exposes only a subset of the flags available with WinHttpSetOption and is not updated with new ones (since XP) at all.

    cheers,
    </wqw>

  17. #17
    Fanatic Member
    Join Date
    Aug 2016
    Posts
    673

    Re: xmlhttp async problem

    Quote Originally Posted by wqweto View Post
    winhttp.Option exposes only a subset of the flags available with WinHttpSetOption and is not updated with new ones (since XP) at all.

    cheers,
    </wqw>
    thank you .
    It is true that these parameter settings are rarely used and there is no reference code

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width