I am using a macro in Outlook VBA to submit a file via POST to a URL:
Set http = New WinHttp.WinHttpRequest
http.Open "POST", UrlToPostTo, False 'True '
http.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
http.setRequestHeader "Content-Type", "multipart/form-data; "
http.Send data
My problem is the page that will accept the request (a file upload page, in this case) is protected by authentication - the initial request for it above will return a login page instead of the page itself.
I have tried to detect if the login page appears and if so, post the username and password as form variables (I'm hoping this is equivalent to a human typing said username and password into a page in the web browser).
So the steps are:
* request URL (include file with post).
* Check if the reponse is the login page.
* If so, then in the same http session, submit the username and password to the URL.
* If the server now processes the original post, good, otherwise I can post it again.
The code looks like:
' if the login page comes back, send credentials '
If (InStr(http.ResponseText, "j_password") > 0) Then
Dim loginData As String
loginData = "j_username=theusername&j_password=thepassword"
http.Open "POST", UrlToPostTo, False
http.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
http.setRequestHeader "Content-Type", "multipart/form-data; "
http.Send loginData
End If
But when I do this, The http.Responsetext is just the login page still (or again?).
Any idea what I'm doing wrong? Is my plan even valid?
(This is related to trying to solve this problem )
I know this thread is ancient and I realize the OP most definitely moved on long ago. I just spent the better part of 3 evenings being humbled by this exact same problem, and this thread kept coming up when I would stop to research more so I thought I would contribute for the next guy who comes along.
The trick is:
- Disable redirects using using the Option property, to stop it from moving on without you. (see comments below)
- Capture the redirect on the output of the Status property, and handle from there.
I'm sure there's other ways, but this seemed pretty elegant to me, and I found lots of other ways to use it.
To use the OPs code example, you could make your request as planned with one exception: The EnableRedirects var, which must come after opening the connection (didn't read that anywhere, just couldn't get it to stick to a closed connection).
Good luck "next guy"!
Dim http As WinHttp.WinHttpRequest
Dim UrlToPostTo As String, UrlRedirectedTo As String
'Your initial request (assuming lots here)
Set http = New WinHttp.WinHttpRequest
http.Open "POST", UrlToPostTo, False
'Stop it from redirecting automatically, so you can capture it
http.Option(WinHttpRequestOption_EnableRedirects) = False 'You can also use the collection index instead of the pretty name
http.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
http.setRequestHeader "Content-Type", "multipart/form-data; "
http.Send
'Now if you have an active session, you should get your desired content
'If it redirected you, you'll have a different status, header etc...
If http.status = "302" Then
Dim loginData As String
'Now lets find out where we're being pointed and POST there
'This may not be the same url you see in your address bar
UrlRedirectedTo = http.GetResponseHeader("Location")
'Also, you may have to do this again to arrive back at the intended resource
loginData = "j_username=theusername&j_password=thepassword"
http.Open "POST", UrlRedirectedTo, False
http.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
http.setRequestHeader "Content-Type", "multipart/form-data; "
http.Send loginData
End If
Some info I found useful in the MSDN maze.
Is the logon page at the same URL as the page you originally submitted to? I don't see any code that changes urlToPostTo
After your first send, you might want to look at the Status property of your request. See the RFC for what each status code means. It could also help to use the GetAllResponseHeaders method to work out exactly what's going on. See MSDN for more on that
It might be possible for you to store the username and password in cookies which would allow you to access your page directly.
Dim doc As WinHttp.WinHttpRequest
Set doc = New WinHttpRequest
doc.Open "POST", url, False
doc.SetRequestHeader "Cookie", "UserID=" & username
doc.SetRequestHeader "Cookie", "Password=" & password
You need to confirm the variable names on your server. You can use a tool like ieHTTPHeaders to inspect the headers when you access the page from the browser to see what you need to do.
Try SetCredentials -- it may work for you, e.g.:
http.Open "POST", UrlToPostTo, False
http.SetCredentials "YourUsername", "YourPassword", 0
http.Send
Source: http://www.automateexcel.com/2005/02/11/excel_vba_winhttprequest_with_login_and/
来源:https://stackoverflow.com/questions/891427/how-to-make-a-post-request-to-a-page-that-may-redirect-to-a-login-page