Qq return (http://fanli.qq.com) and elong (http://www.elong.com) cooperative development of the joint login scheme in the process of joint debugging found a strange phenomenon: the same QQ number jump to the elong site multiple times, sometimes we find that the login status on the elong side can be set, but sometimes we find that the login status cannot be set at all.
Through httpwatch packet capture, it is found that the request series that can log on normally are:
302 http://app.elong.com/fanli/qq_login.php? Xx
200 http://trip.elong.com/home/passport.php? Xx
200 http://www.elong.com/myelong/lohoologin.aspx? Xxx
The jump sequence has normal return codes: 302 and 200;
But the occasional jump request series are:
302 http://app.elong.com/fanli/qq_login.php? Xx
200 http://trip.elong.com/home/passport.php? Xx
Aborted http://www.elong.com/myelong/lohoologin.aspx? Xxx
It indicates that the last request has been dropped by the browser abort when the server has not returned it. After communicating with elong's friends, they will find that lohoologin. aspx is the core part of setting the logon state. If this aspx cannot be set properly, the user cannot log on normally.
The cause of the problem is basically found here, that is, the final request lohoologin. because aspx is dropped by abort, what causes the request to fail to be sent. aspx is composed of passport. PHP issued, look at passport. PHP's response should be clear:
<IFRAME src = http://www.elong.com/myelong/lohoologin.aspx? XXXX> </iframe>
<SCRIPT>
SetTimeout ('window. Top. Location = "http://fanli.qq.com/go.php? XXX "', 3000 );
</SCRIPT>
That is to say, passport. php first sends a request lohoologin. aspx through IFRAME, and then waits 3 s to redirect itself to the http://fanli.qq.com/go.php? Xxx
The logic assumption here is: lohoologin. aspx can be returned within 3 s. When the network conditions are good, the logic here is indeed correct, but our network environment is very bad, to some extent, we cannot guarantee that the aspx can be returned within 3 S. Once 3 s cannot be returned, setTimeout will execute: window. top. location = "http://fanli.qq.com/go.php? ", To redirect the current page, and the HTTP request sent by the current page but not returned will be dropped by the browser abort, once lohoologin. aspx cannot respond, so it cannot set the logon cookie in the browser. Of course, it cannot implement the combined logon.
At this point, we can think that the cause of the problem has already come to fruition. However, tenfy believes that it is still the reason to use its own knowledge. To further confirm this conclusion, tenfy has written two test codes in its own development environment:
Testabort.html:
<Body> <IFRAME id = "loginiframe" src = "testabort. PHP "mce_src =" testabort. PHP "> </iframe> <br/> <SCRIPT type =" text/JavaScript "> <br/> <! -- <Br/> function _ redirect () {<br/> window. location. href = 'HTTP: // fanli.qq.com '; <br/>}; <br/> setTimeout (_ redirect, 3000 ); <br/> // --> <br/> </SCRIPT> </boby> <br/>
Testabort. php:
<? Php <br/> sleep (5); <br/> echo "hello"; <br/>?>
Very simple, the main test in the IFRAME request testabort. php sleep 5S, so that testabort.html is redirected after more than 3 s, then capture the packet can see:
+ 0.000 0.019 708 954 get 200 text/html http://fanli2.qq.com: 13601/test/testabort.html
+ 0.073 3.152 714 0 get (aborted) * http://fanli2.qq.com: 13601/test/testabort. php
Here we can prove that the previous implementation is indeed because the returned Time in IFRAME is greater than 3 s, resulting in the request being dropped by the browser abort.
After the cause of the problem is clear, the solution is simple:
The redirection time cannot be determined by setTimeout, but is determined by the response onload in IFRAME and then the redirection can be executed to avoid this problem:
VaR IFRAME = document. getelementbyid ('loginiframe'); <br/> If (IFRAME) {<br/> IFRAME. src = 'testabort. PHP '; <br/> If (IFRAME. attachevent) {<br/> IFRAME. attachevent ("onLoad", function () {<br/> _ redirect (); <br/>}); <br/>} else {<br/> IFRAME. onload = function () {<br/> _ redirect (); <br/>}; <br/>}< br/>}