zoukankan      html  css  js  c++  java
  • C#客户端与Django服务器端对接——HTTP协议之POST&GET

    这段时间一直在搞C#客户端与Django搭建的服务器端对接的工作。

    从最开始的不知道怎么用Django写服务器端来处理POST请求,到现在能让服务器端接受POST或GET请求并打印出来。虽然客户端还没有登录成功(因为response还没有写好),不过已经取得了部分成果。

    任务分析:C#客户端有一个登录界面和一个登录后的界面,用户需要在登录界面输入用户名和密码才能登录成功,而输入用户名和密码后,单击“登录”按钮,触发相应事件,客户端会向以本机作为服务器的某个地址POST用户名和密码,而在客户端单击“登录”按钮之前,需要先启动用django在本机上搭建的本地服务器,当服务器收到客户端的POST请求后,服务器端需接收POST过来的用户名和密码并和django关联的数据库后台进行验证,验证成功后response一个正确的值给客户端,客户端此时才能跳转到另一个界面。

    编译环境:win10专业版 + VS2013 + Python3.5 + Django1.8框架

    首先贴上客户端用GET方式请求的代码:

    public string GET(string url)
            {
                req = (HttpWebRequest)WebRequest.Create(new Uri(url));
                req.AllowAutoRedirect = true;
                req.CookieContainer = Token;
                req.Method = "GET";
                req.Timeout = 10000;
                req.ContentType = "application/json; charset=utf-8";
    
                try
                {
                    //工厂方法
                    //New Response
                    HttpWebResponse response = (HttpWebResponse)req.GetResponse();
                    //Set Cookie
                    string setCookie = response.Headers.Get("Set-Cookie");
                    //检查Response中是否含有Set-Cookie
                    if (!string.IsNullOrWhiteSpace(setCookie))
                    {
                        Token = new CookieContainer();
                        string[] kvp = setCookie.Split(new char[] { '=', ';' });
                        Cookie cookie = new Cookie(kvp[0], kvp[1]);
                        cookie.Domain = req.Host.Split(':')[0];
                        Token.Add(cookie);
                    }
    
                    if (response.StatusCode == HttpStatusCode.Found)
                    {
                        response.Close();
                        return this.GET(response.Headers["Location"]);
                    }
    
                    //Get Response Stream
                    StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                    res = sr.ReadToEnd();
                    sr.Close();
                    response.Close();
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
                return res;
            }
    private static HttpResqust httpReq=new HttpResqust();
    
            private static string Operator(string url)
            {
                var res = httpReq.GET(url);
                return res;
            }
    string postData = "username=" + username + "&" + "password=" + password;
     string opData = Operator(loginAPI + "?" + postData);          //其中LoginAPI指向 ”http://localhost:8080/login/“
                Log(opData);
                try
                {
                    op = JsonHelper.ParseFromJson<Operator>(opData);
                }
                catch
                {
                    op = null;
                    return "Login error";
                }
                return "OK";   

    服务器端django代码:

    在项目的appviews.py中自定义一个客户端登录的方法:

    def client_login(request):      #自定义一个方法,方法名字不要写成login,因为django有login模块
    
        if request.method=='GET':                   #用GET方法来获取从HTML传递过来的表单内容
            username=request.GET.get('username','')    #获取C#客户端GET过来的用户名和密码
            password=request.GET.get('password','')
            print(username,password)
        else:
            print("come on")   #测试

    接着在appurls.py中添加url的地址:

    urlpatterns = [
    
                   url(r'^login/$', views.client_login,name='client_login'),
                   
    ]

    其中正则表达式 r'^login/$' 对应”http://localhost:8080/login/“ ;

    同时在  系统文件settings.py中配置相关代码:

    INSTALLED_APPS = (
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app',    #添加应用名字
    )
    
    ROOT_URLCONF = 'app.urls'   

    以上,服务器端的代码已完成,接着在项目文件夹下打开命令行窗口,执行 python manage.py runserver 8080 ,此时已经在8080端口启动服务器。

    接着单击客户端登录界面的”登录“按钮,python的命令行窗口就能打印出用户名和密码了,表明服务器端已经能接收客户端的GET请求了。

    Another——>再贴上客户端用POST方式请求的代码:

    public string POST(string url, string postData)
            {
                req = (HttpWebRequest)WebRequest.Create(new Uri(url));
                req.AllowAutoRedirect = true;
                req.CookieContainer = Token;
                req.Method = "POST";
                req.Timeout = 10000;
                req.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
    
                try
                {
                    //通过表单的形式提交参数
                    //Convert Data
                    byte[] data = Encoding.UTF8.GetBytes(postData);
                    req.ContentLength = data.Length;
                    //写入数据流
                    //Send Data
                    Stream stream = req.GetRequestStream();
                    stream.Write(data, 0, data.Length);
                    stream.Close();
                    //工厂方法
                    //New Response
                    HttpWebResponse response = (HttpWebResponse)req.GetResponse();
    
                    string setCookie = response.Headers.Get("Set-Cookie");
                    //检查Response中是否含有Set-Cookie
                    if (!string.IsNullOrWhiteSpace(setCookie))
                    {
                        Token = new CookieContainer();
                        string[] kvp = setCookie.Split(new char[] { '=', ';' });
                        Cookie cookie = new Cookie(kvp[0], kvp[1]);
                        cookie.Domain = req.Host.Split(':')[0];
                        Token.Add(cookie);
                    }
    
                    if (response.StatusCode == HttpStatusCode.Found)
                    {
                        response.Close();
                        if (response.Headers["Location"].Contains("login"))
                            if (ReloginNotify != null)
                                ReloginNotify();
                        return this.GET(response.Headers["Location"]);  
                    }
                    //Set Cookie
                    //Get Response Stream
                    StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                    res = sr.ReadToEnd();
                    sr.Close();
                    response.Close();
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
    
                return res;
            }
         string postData = "username=" + username + "&" + "password=" + password;
             var res = httpReq.POST(loginAPI, postData);          //其中LoginAPI指向 ”http://localhost:8080/login/

      Log(res);

    try
         {
           op
    = JsonHelper.ParseFromJson<Operator>(res);
         }

    catch
         {
           op
    = null; return "Login error";
         }

         return "OK";

    客户端改用POST方式请求后,此时需要更改服务器端的部分代码,其他配置保持不变,只需更改处理客户端请求的方法即可:

    def client_login(request):      #自定义一个方法,方法名字不要写成login,因为django有login模块
    
        if request.method=='POST':
            username=request.POST.get('username','')    #获取C#客户端POST过来的用户名和密码
            password=request.POST.get('password','')
            print(username,password)
        else:
            print("come on")   #测试

    此时客户端的POST请求和服务器端的处理客户端的代码已经更新。

    可当我执行 python manage.py runserver 8080 后,客户端单击”登录“按钮,在python的命令行窗口始终输出 POST 403 错误,而且在django的各个位置打印数据,发现POST请求始终无法连 def client_login(request) 这个方法都进不去,然后我反复检查C#的POST代码,一直找不出bug在哪儿。。。

    直到今晚在师兄几句话的指点下,让我检查一下django在处理POST请求的时候是不是需要配置哪些参数,或者django是不是限制了POST的请求等等。

    终于在一篇技术博客找到了相应的解决方法,贴上地址:http://blog.csdn.net/yisuowushinian/article/details/46137511

    命令行窗口出现 403 错误是 因为django默认的配置MIDDLEWARE_CLASSES中一个中间件CSRF(跨站请求伪造)对POST请求做了验证,

    在 项目文件/setting.py 中,找到如下配置,

    MIDDLEWARE_CLASSES = (
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        #'django.middleware.csrf.CsrfViewMiddleware',           #拒绝POST请求的罪魁祸首
       # 'django.middleware.csrf.CsrfResponseMiddleware',             #已注释
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'django.middleware.security.SecurityMiddleware',
    )

    将图中代码注释掉即可,此时再执行 python manage.py runserver 8080 ,点击”登录“按钮,就能在服务器端的命令行窗口打印用户名和密码了。

    效果如下:

    客户端:

    服务器端python的命令行窗口:

    至此,已完成服务器端接收客户端POST或GET请求的数据了,还差对response做处理,所以仍未登录成功。继续努力!

  • 相关阅读:
    Shell,Bash,等脚本学习(有区别)
    nfs 服务器
    awk的简单使用
    GPRS研究(3):NO CARRIER错误的含义解释
    信号量
    Linux 的多线程编程的高效开发经验
    getaddrinfo()函数详解
    iOS 知识点
    UITableView拉伸效果
    在Xcode中使用Git进行源码版本控制
  • 原文地址:https://www.cnblogs.com/danieldong/p/5453404.html
Copyright © 2011-2022 走看看