vexed! POST returns a 302 found object moved error

2019-07-13 12:02发布

问题:

Someone please help - been struggling with this lousy problem!

What I'm doing - I have an ASPX page from which I originate a GET and then a POST to a HTTPS page with a view to login to it. I have spent quite a bit of time comparing my GET and POST construction to a browser GET/POST using fiddler (protocol analyzer) and my requests are fine.

However, when I try login through the browser, everything works fine and it logs in. When I run my page, I can see the correct GET and POST, but I get a 302 found 'object moved error'

Originally I thought this was a cookie issue, but after much experimentation I'm pretty sure this has nothing to do with cookies. I have disabled cookies AND javascript on the browser and tried, and the pages work fine without either. I then simulated the exact GET/POST.

This is my situation:

  1. My GET and the browsers GET are EXACTLY THE SAME
  2. The 200 OK response from the site is EXACTLY the same EXCEPT three VIEWSTATE variables which have slightly different lengths (why? why different even if GET is same?)
  3. My POST and the browsers POST are EXACTLY the same EXCEPT the 3 Viewstate variables (I fill it correctly from the GET)
  4. And yet, the browser logs in, while I get a 302 found / object moved errror.

A couple of other things -

a) I copied the POST response from a recent browser POST and replaced my POST params with this browser POST and that got me the right response! This indicates that
- my headers are just fine
- my coding setup / environment etc. are fine
- something fishy in the VIEWSTATE values, which can only be because the browser sent it to me in the first place (there is no corruption in my parsing the GET VIEWSTATE variables and using it in POST, it's perfectly fine)

update I have also tried WebClient just to check - no difference, same 302. update The object moved basically points to a error page which says 'a serious error occurred blah blah' - the POST is causing a error at the server, and the ONLY difference between the good POST (of the browser) and my POST are the Viewstate variables.

So - WHAT AM I DOING WRONG? Why is this cruel world tormenting me?!!

(PS - one other difference in the browser sequence, not sure how it matters)

Browser:
CONNECT
GET
GET (for a favicon, which returns an error)
CONNECT
POST (success)
Me:
CONNECT
GET
POST (flaming failure, 302 - page moved)

and for those who care, my POST header construction code

    HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(URL);
    myRequest.UserAgent = chromeUserAgent;

    //myRequest.CookieContainer = cCookies;
    myRequest.ContentType = "application/x-www-form-urlencoded";
    myRequest.Accept = chromeAccept;
    myRequest.Referer = url;
    myRequest.AllowAutoRedirect = false;
    myRequest.Host = "thesitethatskillingme.com";
    myRequest.Headers.Add("Origin", "https://thesitethatskillingme.com");
    myRequest.Headers.Add("Accept-Encoding", chromeAcceptEncoding);
    myRequest.Headers.Add("Accept-Language", chromeAcceptLanguage);
    myRequest.Headers.Add("Accept-Charset", chromeAcceptCharset);
    myRequest.Headers.Add("Cache-Control", "max-age=0");
    myRequest.ServicePoint.Expect100Continue = false;
    myRequest.Method = "POST";
    myRequest.KeepAlive = true;

    ASCIIEncoding ascii = new ASCIIEncoding();
    byte[] bData = ascii.GetBytes(data);

    myRequest.ContentLength = bData.Length;

    using (Stream oStream = myRequest.GetRequestStream())
        oStream.Write(bData, 0, bData.Length);

...and then read stream etc. no cookies.

回答1:

I finally figured it out - and hopefully someone else who chances upon the same problem does not have to go through this again. It's possible that most HTTP gurus and people familiar with WWW development would never hit it, but a newbie quite well could.

So what was the problem? I had narrowed down the problem to VIEWSTATE which I always suspected (see my post above...). It turns out that all I had to do was to Server.UrlEncode the parsed VIEWSTATE values before putting them onto POST - that's it. It took me all day to get to that.

SO, as a learning to other newcomers

  • If you are trying to POST to a page through code and need to send it VIEWSTATE variables that you parsed from GET, then first Server.UrlEncode it before creating the parameters - for e.g.

  • do GET
  • get the response stream into a string
  • parse the string (I use HtmlAgilityPack- fabulous)
  • param1 = name +"="+Server.UrlEncode(value)+"&"
  • POST param = param1+param2+... -send this in POST - voila, it works

because I have never, ever programmed with HttpWebRequest etc., I started by narrowing down my problem by eliminating cookies, javascript, GET construction, POST construction one-by-one using fiddler (great analyzer tool, free) and then finally did byte-comparison using BeyondCompare, and that's when I caught the VIEWSTATE variable modifications.

I learnt a lesson on URL encoding, and hopefully you won't have to!