首先Express实现一个简单的http服务器,支持get,post请求:
var express = require('express');
var url = require('url');
var query=require('querystring');
var app =express();
app.listen(3000);
app.all('/login',function(req,res){
//获取url的字面对象格式
var jsonurl = url.parse(req.url,true);
var jsonobj = jsonurl.query;
var rescode = 'fasle';
if (req.method=="GET"){
console.log("Query:\t"+JSON.stringify(jsonobj)); //查询字段的json字符串格式,并非对象格式
if(jsonobj.user=='tyrant' && jsonobj.password=='123'){
rescode = 'true';
}
var result ={
'user':jsonobj.user,
'password':jsonobj.password,
'resultcode':rescode
}
res.send(JSON.stringify(result));
}
else{
var postdata = '';
req.on("data",function(chunck){
postdata+=chunck;
});
req.on("end",function(){
var params = query.parse(postdata);//字符转化为数组对象
if(params['user']=='xiaozhun' && params['password']=='123'){
rescode = 'true';
var result ={
'user':params['user'],
'password':params['password'],
'resultcode':rescode
}
res.send(JSON.stringify(result));
}});
}
});
注意两点:
注意格式转换,其中三处格式转化:
var jsonurl = url.parse(req.url,true);
这是调用nodejs的url模块实现,对url格式字符串的对象化var jsonobj = jsonurl.query;JSON.stringify(req.query)
这是从url对象中提取query字段,就是url后面”?”后的部分,这里提取出来的就是js的对象,JSON.stringify()就是将js对象转化为字符串。query.parse(postdata);
这是nodejs模块querystring的功能,将键值对集合的字符串转化为js的数组对象,具体函数申明如下:querystring.parse(str, [sep], [eq], [options]) //sep为分隔符,默认为& , eq为赋值符号,默认为=,option为能转化字符串的最大长度,默认为1000
get和post的数据处理方式不同,get可简单从url中获取字段,post数据量较大,只能通过事件监听,分别监听”data”,”end”事件,获取post中的数据。
前端,网络通信采用MKNeworkit,直接上代码:分别是post和get方式传递用户名密码
-(void)loginPost:(NSString*)user pass:(NSString*)password{
MKNetworkEngine * engine = [[MKNetworkEngine alloc]initWithHostName:@"127.0.0.1:3000" customHeaderFields:nil];
NSMutableDictionary* params = [[NSMutableDictionary alloc]init];
[params setValue:user forKey:@"user"];
[params setValue:password forKey:@"password"];
MKNetworkOperation * op = [engine operationWithPath:@"/login?" params:params httpMethod:@"POST"];
NSLog(@"url:%@",[op url]);
[op addCompletionHandler:^(MKNetworkOperation *completedOperation) {
NSData* data = [completedOperation responseData];
NSError* err = nil;
NSDictionary* dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&err];
if(dict&&(err==nil)){
NSLog(@"success 返回结果:%@",dict);
}else{
NSLog(@"failed 返回结果:%@",dict);
}
} errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {
NSLog(@"error:%@",[error localizedDescription]);
}];
[engine enqueueOperation:op];
}
-(void)loginGet:(NSString*)user pass:(NSString*)password{
NSString* path = [[NSString alloc]initWithFormat:@"login?user=%@&password=%@",user,password];
MKNetworkEngine *engine = [[MKNetworkEngine alloc]initWithHostName:@"127.0.0.1:3000" customHeaderFields:nil];
MKNetworkOperation *op = [engine operationWithPath:path params:nil httpMethod:@"GET"];
[op addCompletionHandler:^(MKNetworkOperation *completedOperation) {
NSData* data = [completedOperation responseData];
NSError* err = nil;
NSDictionary* dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&err];
if(dict&&(err==nil)){
NSLog(@"success 返回结果:%@",dict);
}else{
NSLog(@"failed 返回结果:%@",dict);
}
} errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {
NSLog(@"error:%@",[error localizedDescription]);
}];
[engine enqueueOperation:op];
}
MKNetworkit主要就是两个类,MKNetworkEngine,MKNetworkOperation,一个负责管理链接队列,包括指定host,生成链接,一个负责链接的具体内容,从最后的[engine enqueueOperation:op];
可见采用的是任务队列。中间有个json数据的转化,因为服务器返回的是json格式的数据。
具体工程参见:
https://github.com/tyrantkemp/mknetwork_express.git
这样能模拟出登陆验证的功能,但是在具体实现中发现一个问题,就是登陆时客户端和服务器通信同步异步问题,具体见下一章