node创建客户端与服务器端(HTTP)
来源:互联网 发布:仿真软件multisim 编辑:程序博客网 时间:2024/04/29 21:49
Transfer-Encoding: chunked
在我用telnet登录服务器的时候,服务器返回信息如下。
其中,我们看到这样一条相应–Transfer-Encoding: chunked
。Transfer-Encoding头信息的默认值是chunked,主要的原因是Node天生的异步机制,这样响应就可以逐步产生。
发送数据块的方式在涉及文件系统的情况下会非常高效。Web服务器对硬盘上的文件托管服务是很常见的。因为Node允许以数据块的形式往相应中写数据,同时他又允许以数据块的方式读取文件。所以我们就可以用ReadStream文件系统API来实现读取文件。(本文讨论的不是这个)
发送一个简单的HTTP请求
//服务端require( 'http' ).createServer( function ( req, res ) { res.writeHead( 200 ); res.end( 'hello world' );}).listen( 4000 );//客户端require( 'http' ).request({// 初始化一个新的http.Client Request对象 host: '127.0.0.1',// 一定不能加http port: 4000, url: '/',// 随意 mehotd: 'GET'}, function (res) { var body = ''; res.setEncoding( 'utf-8' ); res.on( 'data', function (chunk) { body += chunk; }); res.on( 'end', function () { console.log( '\n We got: \033[96m' + body + '\033[39m'); });}).end();
上述代码中,首先调用了一个request方法。此方法用于初始化一个新的http.Client Request对象。注意的是,我们收集的数据是分块的,连接的服务器会返回不同的数据块,只有所有的数据块全部被收集到也能得到完整的相应。当然,也有可能所有的数据在一个data事件中到达了,我们无从而知。
另一个重要问题是:这段代码在chunk都是ascii码数据或者数据量比较少时是没有问题,但如果你的数据是大量中文的话,恭喜你,中枪了,会出现乱码。其原因是两个chunk(Buffer对象)的拼接并不正常,相当于进行了buffer.toString() + buffer.toString()。如果buffer不是完整的,则toString出来后的string是存在问题的(比如一个中文字被截断)。具体可以参见朴灵写得这篇文章:http://cnodejs.org/topic/4faf65852e8fb5bc65113403
在此例中,我们监听end事件,然后将body输出到控制台。另外,我们通过相应对象设置编码为utf-8,因为输出的是文本。
在上面的例子中,调用完request之后,还需要调用end。
这是因为,在创建完一个请求之后,在发送给服务器前还可以和request对象进行交互。
querystring
这是node的一个模块,用来对url参数进行解析(parse)和转换为字符串(stringify)。
var qs = require('querystring');console.log( qs.stringify({name: 'real',age:20}) );console.log( qs.stringify({学生: '皖林',age:20}) );console.log( qs.parse( 'name=皖林&age=12' ));
输出结果为:
name=real&age=20%E5%AD%A6%E7%94%9F=%E7%9A%96%E6%9E%97&age=20{ name: '皖林', age: '12' }
对于要转换为url参数字符串的对象,其键和值都是经过编码的,如果是中文,可以看到明显区别。
客户端
//客户端var http = require( 'http' ), qs = require( 'querystring' );function send( theName ) { var data = qs.stringify({ name:theName }); var request = require( 'http' ).request({// 初始化一个新的http.Client Request对象 host: '127.0.0.1', port: 3000, url: '/',// 随意 mehotd: 'POST', headers: { 'Content-Type':'application/x-www-form-urlencoded', 'Content-Length': data.length, } }, function ( res ) { res.setEncoding( 'utf-8' );// var body = ''; res.on( 'data', function ( chunk ) { // body += chunk; }) res.on( 'end', function () {// console.log(body); console.log('\n \033[90m request complete! \033[39m'); process.stdout.write( '\n your name: '); }); }) request.end( data ) ;}process.stdout.write( '\n your name: ');// 客户端启动后,输出your nameprocess.stdin.resume();// 等待输入process.stdin.setEncoding( 'utf-8' );// 设置输入流编码process.stdin.on( 'data', function ( name ) { send( name.replace( '\n', '' ) );});
有几个需要注意的地方:
- request( {},function(res){} )的第一个参数需要需要显式加上header。否则会报错:
Error: socket hang up
。 - 尽管我的res.on( ‘data’ , function(){})中没有做任何处理,但这应该是必需的(我尝试过,没有检测data事件的时候,会出问题,问题是无法检测到res.on( ‘end’, funciton(){})事件,我搜索了SO,说是将end换成close或finish有帮助。But,It still doesn’t work for me。我的node版本是v4.4.7。为此,我付出了2个小时的时间,甚至更多。)
- 分块问题,见上面。
服务端
var qs = require( 'querystring' );require( 'http' ).createServer( function ( req, res ) { var body = ''; req.on( 'data', function ( chunk ) { // body += chunk; }) req.on( 'end', function (){//所有数据接收完毕 res.writeHead( 200 ); res.end( 'Done' ); console.log( '\n got name: \033[90m' + qs.parse( body ).name + '\033[39m'); })}).listen( 3000 );
服务端同样也是按数据块传输的。这里的res.end( 'Done' );
,在我的客户端中可以使用body接收到,即注释的部分代码。
参考
了不起的Node.js
http://cnodejs.org/topic/4fc7789a8be5d070121141cd
小结
时不我待。
- node创建客户端与服务器端(HTTP)
- Android客户端与Web服务器端Http通信
- Http客户端与服务器端的交互
- 通俗易懂客户端与服务器端交互原理(HTTP数据请求与HTTP响应,包括Servlet部分)
- 通俗易懂客户端与服务器端交互原理(HTTP数据请求与HTTP响应,包括Servlet部分)
- 通俗易懂客户端与服务器端交互原理(HTTP数据请求与HTTP响应,包括Servlet部分)
- 客户端与服务器端交互原理(HTTP数据请求与HTTP响应)
- 通俗易懂客户端与服务器端交互原理(HTTP数据请求与HTTP响应,包括Servlet部分)
- 通俗易懂客户端与服务器端交互原理(HTTP数据请求与HTTP响应,包括Servlet部分)
- iOS客户端与服务器端Node.js实现通信的方法
- Node.js HTTP 服务器与客户端
- C#服务器端与客户端通信(客户端)
- Node.js服务器端编程实践(一):服务器创建与hello world应答
- WebGoat之HTTP BASICS(客户端与服务器端的交互方式)-2016.01.02
- 如何在HTTP客户端与服务器端之间保持状态
- Node.js HTTP客户端
- node.js http客户端
- nodejs服务器与服务器之间通讯问题(nodejs服务器端创建客户端)
- 扩展名改为pyw后无法运行的问题记录
- Git常用命令速查表
- Leetcode 159 & 340 Longest Substring with At Most Two/K Distinct Characters
- mysql安装图解 mysql图文安装教程(详细说明)
- 硅谷NFX协会与Synereo合作加快ÐApp开发团队建设
- node创建客户端与服务器端(HTTP)
- t_user is not mapped [from t_user as u where u.loginname = :loginname and u.password =:password]
- 51Nod-1607-卷积和
- 【CSS】盒子模型
- Python学习第二天
- 马踏棋盘(递归)
- [Leetcode] Bitwise AND of Numbers Range
- 百分位数概念学习
- POJ_1434_Fill the Cisterns!