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做处理,所以仍未登录成功。继续努力!

原文地址:https://www.cnblogs.com/danieldong/p/5453404.html