您的位置:首页 > 理论基础 > 计算机网络

C#客户端与Django服务器端对接——HTTP协议之POST&GET

2016-05-03 00:04 435 查看
这段时间一直在搞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代码:

在项目的app\views.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")   #测试


接着在app\urls.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做处理,所以仍未登录成功。继续努力!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: