突破365租售宝登录验证码
问题:365租售宝,通过sessionid保持客户登录状态,如何才能让验证码图片与对应的sessionid实现登录。
这个问题用了好几天的时间。终于搞定了,期间学到了很多东西。
实现思路:
1,绑定帐号页面定义两个全局变量,sessionid,imgurl;在页面首次加载时调用获取图片方法,将图片缓存到本地,同时将本地图片url给imgurl,讲set-cookie的值给sessionid.
2,前台页面img的src绑定imgurl,隐藏域绑定sessionid,这样页面初始化就可以得到它们的值。
3,在后台通过Request.Form拿到客户在text中输入的验证码code,和隐藏的sessionid,同时把他们
赋值给dynamic param.
4,在具体的Login方法中,先向登录页面请求(get)一次,这是网站会返回一个set-cookie,然后
将param.sessionid添加到httpclient的同名为PHPSESSID的cookie中,这是就会取代刚才的set-cookie.然后在添加用户名,密码,验证码,开始post,就成功了。
对于发房租房等等一样的思想。
以上内容为最后的总结,下面是解决这个问题时学到的一些知识。
这两天一直想实现一个思想,就是在前台单击确定,然后把用户名和密码发送到后台,后台执行
过后返回来图片url,然后我在前台设置图片url,可是一直都没有实现。
下面是一些解决这个问题时获得的其他的知识。
1,
(1)后台运行js方法:
ClientScript.RegisterStartupScript(Page.GetType(), "key1", "showImg('" + url + "')", true);
ClientScript.RegisterClientScriptBlock(Page.GetType(), "key1", "showImg('" + url + "')", true);
四个参数,1为页面类型,2为key,3为js方法(不能是jQuery方法),4指定为true后就可以不用在3参中写script;
第二个函数不能正常执行,不知道为什么。
(2)js运行后台函数,或者获取后台变量的值。
var message = "<%=message %>"; //获取后台变量值 var message = "<%=Get() %>"; //运行后台方法并取得返回值
2,下面是一个例子,单击保存账号时,后台调用js方法,设置图片url
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script type="text/javascript" src="jquery.easyui.min-1.1.2.js"></script> <script src="jquery-1.4.2.min.js" type="text/javascript"></script> <script type="text/javascript" language="javascript"> var showImg = function (url) { var img = document.getElementById("imgcode"); img.parentNode.parentNode.style.display = ""; img.src = url; } </script> </head> <body> <form id="form1" runat="server"> <div id="logindiv" > <table style="margin: 15px;" id="tb1"> <tr> <td> 用户名: </td> <td> <input type="text" class="reselect" id="username" name="username" runat="server" style="width: 200px;" /> </td> </tr> <tr> <td> 密码: </td> <td> <input type="text" class="reselect" id="password" runat="server" name="password" style="width: 200px;" /> </td> </tr> <tr style="display:none"> <td> <img src="" id="imgcode" alt="验证码" /> </td> <td> <input type="text" class="reselect" id="code" runat="server" name="code" style="width: 200px;" /> </td> </tr> <tr> <td> </td> <td> <asp:Button ID="baocun" runat="server" Text="保存账号" CssClass="sub" OnClick="baocun_Click" /> <a href="#" id="zhuceurl">没有账号,立即注册</a> </td> </tr> </table> </div> </form> </body> </html>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Runtime.Serialization.Json; using System.IO; using System.Text; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void baocun_Click(object sender, EventArgs e) { string name = Request.Form["username"]; string password = Request.Form["password"]; string code = Request.Form["code"]; string url="http://wo.house365.com/validcode.php?0.8287814355268701"; ClientScript.RegisterStartupScript(Page.GetType(), "key1", "showImg('" + url + "')", true); // ClientScript.RegisterClientScriptBlock(Page.GetType(), "key1", "showImg('" + url + "')", true); } }
3,下面是把扩展object,可以转为json形式。
/// <summary> /// 序列化扩展类 /// </summary> public static class Serializer { /// <summary> /// 将Object对象序列化为Json字符串 /// </summary> /// <param name="obj"></param> /// <returns></returns> public static string ToJson(this object obj) { System.Runtime.Serialization.Json.DataContractJsonSerializer seria = new DataContractJsonSerializer(obj.GetType()); using (MemoryStream mstream=new MemoryStream()) { seria.WriteObject(mstream, obj);//讲对象obj写入内存流 mstream.Position = 0;//设置流的位置为0,因为刚写入的流位置在末尾 StreamReader rstream = new StreamReader(mstream, Encoding.UTF8); return rstream.ReadToEnd().ToString();//将流以string的形式返回 } } }
4,另外一些小知识点
(1)easyui的window中height指定为auto不显示
(2)img.parentNode.parentNode.style.display = "";父亲的父亲显示
过了一两天,周一早上我吃饭的时候开始思考如何解决这个问题,现在想到了。
1,直接让url通过绑定后台方法<%= fun()%>来得到url,需要是public的。
然后单击是判断,如果是vip365,显示验证码,并且如果输入验证码的text为空,return false;
然后我还定义了一个全局变量httpcliet.通过带有ref参数的函数,调用登录,这样就保证了httpclient唯一。
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script type="text/javascript" src="jquery.easyui.min-1.1.2.js"></script> <script src="jquery-1.4.2.min.js" type="text/javascript"></script> </head> <body> <form id="form1" runat="server"> <div id="logindiv"> <table style="margin: 15px;" id="tb1"> <tr style="display:none"> <td> <img src="" id="imgcode" alt="验证码" /> </td> <td> <input type="text" class="reselect" id="code" runat="server" name="code" style="width: 200px;" /> </td> </tr> <tr> <td> </td> <td> <asp:Button ID="baocun" runat="server" Text="保存账号" CssClass="sub" OnClick="baocun_Click" /> <a href="#" id="zhuceurl">没有账号,立即注册</a> </td> </tr> </table> </div> </form> </body> </html> <script type="text/javascript" language="javascript"> $(function () { $("#logindiv").click(function () { if (true) { $("#code").parents("tr").css("display", ""); //显示图片 $("#imgcode").attr("src", "<% =GetImgUrl() %>"); //获取后台方法返回值 } if ($("#code").val() == "") { return false; } }); }); </script>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Runtime.Serialization.Json; using System.IO; using System.Text; using System.Dynamic; public partial class _Default : System.Web.UI.Page { public HttpClient httpclient = new HttpClient();//初始化一个全局对象 public string GetImgUrl() { httpclient.Url = "http://wo.house365.com/validcode.php?0.8287814355268701";//为全局变量赋值,并且返回 return httpclient.Url; } public string Login(ref HttpClient httpclient,dynamic param) { //使用前面修改过的HttpClient对象;其他类库调用 return httpclient.Url; } protected void baocun_Click(object sender, EventArgs e) { string code = Request.Form["code"]; dynamic param = new ExpandoObject(); param.code = code;//给动态变量赋值 Login(ref httpclient, param);//调用参数特别的函数 } } public class HttpClient { public HttpClient() { } public string Url; }
这是目前我遇到过的最大难题,通过这次事,我发现平时要思考工作中的问题,只靠工作的时间不够。虽然验证码登录仍然错误,但是我成长了。
5,如何获取配置文件中的连接字符串?
string str = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString; 以上是在ASP.NET配置文件中获取连接字符 串,以上方法是写在一个类里的也就是后台 不能在三层架构里拿到这个字符串. 如果在前台代码里写是: ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString%>" "<%$ %>"是ASP.NET2。0中新出现的表达式,用于加 载资源内容或者包含在配置文件中的特定内容。 ConnectionStrings:NorthwindConnectionString表示引用位于Web.config文件的ConnectionStrings配置节中,名为NorthwindConnectionStrings 的连接字 符串配置信息。
6,我尝试过将httpclient定义为全局static变量,登录成功了,但是这是多个客户端同时共享的一个变量,因此如果多个帐号登录,可能会出错。
7ASP.NET ViewState详解 http://www.cnblogs.com/wwan/archive/2010/11/18/1880357.html
8,有关lock :http://blog.vckbase.com/song/articles/444.aspx
9,前台绑定后台:http://www.cnblogs.com/lerit/archive/2010/10/22/1858007.html