Node.js HTTP 使用详解
对于初学者有没有发觉在查看Node.js官方API的时候非常简单,只有几个洋文描述两下子,没了,我第一次一口气看完所以API后,对于第一个示例都有些懵,特别是参数里的request和response,究竟是如何通过参数工作的,如果并发量大如何确保每个人访问和提交的数据不干扰等等。都没有教你具体如何在开发中使用,如何着手写代码,给你一个Event 'close',只说了下在服务器关闭时触发,完了。如果没有了解EventEmitter的核心事件,可能还真不知道如何抒写代码并在开发中真正使用。而http server创建的服务对象已经继承了EventEmitter,所以可以直接使用on进行监听即可。学学util包中的inherits是如何继承EventEmitter的就应该略知一二了。
在官方文档的API中有服务器对象和回调函数参数返回参数的对象,response和request对象各有两种不同。一种是server级别的一种是client级别的。
关于HTTP部分大致分为如下的重要点:
直接通过http对象使用的有:
一、http.STATUS_CODES
二、http.createServer
三、http.request(http.ClientRequest)
四、http.get
五、http.globalAgent
作为回调参数使用的对象有:
http: {
STATUS_CODES: {
'100': 'Continue',
'101': 'Switching Protocols',
'102': 'Processing',
'200': 'OK',
'201': 'Created',
'202': 'Accepted',
'203': 'Non-Authoritative Information',
'204': 'No Content',
'205': 'Reset Content',
'206': 'Partial Content',
'207': 'Multi-Status',
'300': 'Multiple Choices',
'301': 'Moved Permanently',
'302': 'Moved Temporarily',
'303': 'See Other',
'304': 'Not Modified',
'305': 'Use Proxy',
'307': 'Temporary Redirect',
'400': 'Bad Request',
'401': 'Unauthorized',
'402': 'Payment Required',
'403': 'Forbidden',
'404': 'Not Found',
'405': 'Method Not Allowed',
'406': 'Not Acceptable',
'407': 'Proxy Authentication Required',
'408': 'Request Time-out',
'409': 'Conflict',
'410': 'Gone',
'411': 'Length Required',
'412': 'Precondition Failed',
'413': 'Request Entity Too Large',
'414': 'Request-URI Too Large',
'415': 'Unsupported Media Type',
'416': 'Requested Range Not Satisfiable',
'417': 'Expectation Failed',
'418': 'I\'m a teapot',
'422': 'Unprocessable Entity',
'423': 'Locked',
'424': 'Failed Dependency',
'425': 'Unordered Collection',
'426': 'Upgrade Required',
'428': 'Precondition Required',
'429': 'Too Many Requests',
'431': 'Request Header Fields Too Large',
'500': 'Internal Server Error',
'501': 'Not Implemented',
'502': 'Bad Gateway',
'503': 'Service Unavailable',
'504': 'Gateway Time-out',
'505': 'HTTP Version Not Supported',
'506': 'Variant Also Negotiates',
'507': 'Insufficient Storage',
'509': 'Bandwidth Limit Exceeded',
'510': 'Not Extended',
'511': 'Network Authentication Required'
}
}
测试用例:
var http = require('http'); http.createServer(function(req,res){
var status = req.url.substr(1);
if( ! http.STATUS_CODES[status])
{
status = '404';
}
res.writeHeader(status,{'Content-Type':'text/plain'});
res.end(http.STATUS_CODES[status]);
}).listen(3000);
测试连接:http://localhost:3000/500 结果输出 Internal Server Error
二、http.createServer
http.createServer是创建一台web服务器的关键所在,是处理请求和回应的主函数出口和出口,我们把http.createServer创建的服务对象定义为server.代码如下。
/**
* Created by Administrator on 14-4-29.
*/ var http = require('http'); /**
* 创建服务器的两种写法,第一种写法如下
* 由于server已经继承了EventEmitter的事件功能,所以可以使用高级函数编写方式监控事件
* @param {Function} request event
*/
var server = http.createServer(function(req,res)
{
//这里的req为http.serverRequest
res.writeHeader(200,{'Content-Type':'text/plain'});
res.end('hello world');
}); /**
* 说明:创建服务器的第二种写法
* 有关server对象的事件监听
* @param {Object} req 是http.IncomingMessag的一个实例,在keep-alive连接中支持多个请求
* @param {Object} res 是http.ServerResponse的一个实例
*/
var server = new http.Server();
server.on('request',function(req,res){
res.writeHeader(200,{'Content-Type':'text/plain'});
res.end('hello world');
}); /**
* 说明:新的TCP流建立时出发。 socket是一个net.Socket对象。 通常用户无需处理该事件。
* 特别注意,协议解析器绑定套接字时采用的方式使套接字不会出发readable事件。 还可以通过request.connection访问socket。
* @param {Object} socket
*/
server.on('connection',function(socket){}); /**
* 源API: Event: 'close'
* 说明:关闭服务器时触发
*/
server.on('close',function(){}); /**
* 说明:每当收到Expect: 100-continue的http请求时触发。 如果未监听该事件,服务器会酌情自动发送100 Continue响应。
* 处理该事件时,如果客户端可以继续发送请求主体则调用response.writeContinue, 如果不能则生成合适的HTTP响应(例如,400 请求无效)
* 需要注意到, 当这个事件触发并且被处理后, request 事件将不再会触发.
* @param {Object} req
* @param {Object} req
*/
server.on('checkContinue',function(req,res){}); /**
* 说明:如果客户端发起connect请求,如果服务器端没有监听,那么于客户端请求的该连接将会被关闭
* @param {Object} req 是该HTTP请求的参数,与request事件中的相同。
* @param {Object} socket 是服务端与客户端之间的网络套接字。需要自己写一个data事件监听数据流
* @param {Object} head 是一个Buffer实例,隧道流的第一个包,该参数可能为空。
*/
server.on('connect',function(req,socket,head){}); /**
* 说明:这个事件主要是对HTTP协议升级为其他协议后的事件监听,如果服务器端没有监听,那么于客户端请求的该连接将会被关闭
* @param {Object} req 是该HTTP请求的参数,与request事件中的相同。
* @param {Object} socket 是服务端与客户端之间的网络套接字。需要自己写一个data事件监听数据流
* @param {Object} head 是一个Buffer实例,升级后流的第一个包,该参数可能为空。
*/
server.on('upgrade',function(req,socket,head){}); /**
* 说明:如果一个客户端连接触发了一个 'error' 事件, 它就会转发到这里
* @param {Object} exception
* @param {Object} socket
*/
server.on('clientError',function(exception,socket){}); /**
* 源API:server.listen(port, [hostname], [backlog], [callback])
* 说明:监听一个 unix socket, 需要提供一个文件名而不是端口号和主机名。
* @param {Number} port 端口
* @param {String} host 主机
* @param {Number} backlog 等待队列的最大长度,决定于操作系统平台,默认是511
* @param {Function} callback 异步回调函数
*/
//server.listen(3000,'localhost',100,function(){}); /**
* 源API:server.listen(path, [callback])
* 说明:启动一个 UNIX 套接字服务器在所给路径 path 上监听连接。
* 可能用处:多路径或渠道数据来源监听分隔
* @param {String} path
* @param {Function} callback
*/
//server.listen('path',function(){}) /**
* 源API:server.listen(handle, [callback])
* 说明:Windows 不支持监听一个文件描述符。
* @param {Object} handle 变量可以被设置为server 或者 socket
* @param {Function} callback
*/
//server.listen({},function(){}); /**
* 说明:最大请求头数目限制, 默认 1000 个. 如果设置为0, 则代表不做任何限制.
* @type {number}
*/
server.maxHeadersCount = 1000; /**
* 源API:server.setTimeout(msecs, callback)
* 说明:为套接字设定超时值。如果一个超时发生,那么Server对象上会分发一个'timeout'事件,同时将套接字作为参数传递。
* 设置为0将阻止之后建立的连接的一切自动超时行为
* @param {Number} msecs
* @param
*/
server.setTimeout(1000,function(){}); /**
* 说明:一个套接字被判断为超时之前的闲置毫秒数。 默认 120000 (2 分钟)
* @type {number}
*/
server.timeout = 120000; /**
* 说明:这里的主机将是本地
* @param {Number} port 端口
* @param {Function} callback 异步回调函数
*/
server.listen(3000,function(){
console.log('Listen port 3000');
});
三 、http.request
http 模块提供了两个函数 http.request 和 http.get,功能是作为客户端向 HTTP服务器发起请求。http.request(options, callback) 发起 HTTP 请求。接受两个参数,option 是一个类似关联数组的对象,表示请求的参数,callback 是请求的回调函数。option常用的参数如下所示。 http.request 返回一个 http.ClientRequest 的实例。
/**
* Created by Administrator on 14-4-30.
*/ var http = require('http'); var server = http.createServer(function(req,res){ }).listen(3000); /**
* 参数配置
* @type {{hostname: string, port: number, method: string, path: string,handers: {}}}
* host:请求的服务器域名或者IP地址
* port:端口
* method:请求方式有POST,GET,INPUT,DELETE,CONNECT,默认为GET
* path:请求地址,可包含查询字符串以及可能存在的锚点。例如'/index.html?page=12'
* handers: 一个包含请求头的对象。
*/
var options =
{
hostname : 'www.google.com',
port : 80,
method : 'POST',
path : '/upload',
handers:{}
}; /**
* 如下特别的消息头应当注意:
* 发送'Connection: keep-alive'头部将通知Node此连接将保持到下一次请求。
* 发送'Content-length'头将使默认的分块编码无效。
* 发送'Expect'头部将引起请求头部立即被发送。
* 通常情况,当发送'Expect: 100-continue'时,你需要监听continue事件的同时设置超时。参见RFC2616 8.2.3章节以获得更多的信息。
*/ /**
* 说明:官方给出的例子
* 应用场景:模拟客服端请求服务器,是一个HTTP 客户端工具,用于向 HTTP 服务器发起请求。
* @param {Object} options
* @param {Function} callback
*/
var req = http.request(options,function(res){
console.log(res);
console.log('STATUS:' + res.statusCode);
console.log('HEADERS:' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data',function(chunk){
console.log('BODY' + chunk);
});
}); req.on('response',function(){ }); req.on('connect',function(){ }); req.on('socket',function(){ }); req.on('upgrade',function(){ }); req.on('continue',function(){ }) //如果在请求过程中出现了错误(可能是DNS解析、TCP的错误、或者HTTP解析错误),返回的请求对象上的'error'的事件将被触发。
req.on('error',function(e){
console.log(e.message);
}); /**
* 源API:request.write(chunk, [encoding])
* 说明:发送正文中的一块。用户可以通过多次调用这个方法将请求正文以流的方式发送到服务器。此种情况建议在建立请求时使用['Transfer-Encoding', 'chunked']请求头。
* @param {Object or String} chunk 参数chunk应当是一个整数数组或字符串。
* @param {String} encoding 参数encoding是可选的,仅在chunk为字符串时可用。
*/
req.write('data\n'); /**
* 源API:request.end(chunk, [encoding])
* 说明:完成本次请求的发送。如果正文中的任何一个部分没有来得及发送,将把他们全部刷新到流中。如果本次请求是分块的,这个函数将发出结束字符'0\r\n\r\n'。如果使用参数data,就等于在调用request.write(data, encoding)之后紧接着调用request.end()。
* @param {Object or String} chunk 参数chunk应当是一个整数数组或字符串。
* @param {String} encoding 参数encoding是可选的,仅在chunk为字符串时可用。
* example: req.end(),req.end('data\n'),req.end('data','utf8'),req.end(chunk)
*/
req.end(); /**
* 阻止一个请求。(v0.3.8中新增的方法。)
*/
req.abort(); /**
* 源API:request.setTimeout(timeout, [callback])
* 说明:一旦给这个请求分配的是一个socket时此函数会被调用
* @param {Number} timeout 毫秒
* @param {Function} callback 回到函数
*/
req.setTimeout(1000,function(){}); /**
* 源API :request.setNoDelay([noDelay])
* 说明:默认有一定的延迟,设置为0表示无延迟
* @param {Number} noDelay
*/
req.setNoDelay(0)
/**
* 源API:request.setSocketKeepAlive([enable], [initialDelay])
* 类似同上
*/
四、http.get
http.get(options, callback) http 模块还提供了一个更加简便的方法用于处理GET请求:http.get。它是 http.request 的简化版,唯一的区别在于http.get自动将请求方法设为了 GET 请求,同时不需要手动调用 req.end()。
/**
* Created by Administrator on 14-4-30.
*/ var http = require('http'); http.createServer(function(req,res){ }).listen(3000); /**
* 说明:由于大部分请求是不包含正文的GET请求,Node提供了这个方便的方法。与http.request()唯一的区别是此方法将请求方式设置为GET,并且自动调用req.end()。
* 应用:服务器端测试客服端请求调试等
* @param {String} url 有效地址
* @param {Function} callback
*/
http.get('http://www.baidu.com/index.html',function(res){
console.log('get response Code :' + res.statusCode);
}).on('error',function(e){
console.log("Got error: " + e.message);
})
Node.js HTTP 使用详解的更多相关文章
- 《Node.js开发实战详解》学习笔记
<Node.js开发实战详解>学习笔记 ——持续更新中 一.NodeJS设计模式 1 . 单例模式 顾名思义,单例就是保证一个类只有一个实例,实现的方法是,先判断实例是否存在,如果存在则直 ...
- node.js的npm详解
一.什么是npm呢 npm(Node Package Manager,node包管理器)是node的包管理器,他允许开发人员在node.js应用程序中创建,共享并重用模块.模块就是可以在不同的项目中重 ...
- Node.js中Async详解:流程控制
安装 npm install async --save 地址 https://github.com/caolan/async Async的内容主要分为三部分 流程控制: 简化九种常见的流程的处理 集合 ...
- Node.js + Express中间件详解
使用中间件 Express是一种路由和中间件Web框架,它具有自己的最小功能:Express应用程序本质上是一系列中间件函数调用. 中间件函数是可以访问请求对象 (req),响应对象(res)以及应用 ...
- 阿里云ECS服务器部署Node.js项目全过程详解
本文详细介绍如何部署NodeJS项目到阿里云ECS上,以及本人在部署过程中所遇到的问题.坑点和解决办法,可以说是全网最全最详细的教程了.同时讲解了如何申请阿里云免费SSL证书,以及一台ECS服务器配置 ...
- Node.js之eventproxy详解
安装 npm install eventproxy --save 调用 var EventProxy = require('eventproxy'); 异步协作 多类型异步协作 此处以页面渲染为场景, ...
- ES6,ES2105核心功能一览,js新特性详解
ES6,ES2105核心功能一览,js新特性详解 过去几年 JavaScript 发生了很大的变化.ES6(ECMAScript 6.ES2105)是 JavaScript 语言的新标准,2015 年 ...
- Js apply 方法 详解
Js apply方法详解 我在一开始看到JavaScript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这 ...
- Js apply()使用详解
Js apply方法详解 我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这 ...
随机推荐
- 关于阿里云ESC上go语言项目编译6l: running gcc failed: Cannot allocate memory
(1)前段时间将自己的阿里云服务器上的系统由centos 6.5换为了ubuntu 14,其他的硬件配置都没有发生改变,将服务器上的数据恢复并且重新安装了golang的编译环境后,发现使用go bui ...
- Jmeter的简单练习
一.安装Jmeter 1.下载Jmeter 下载地址:http://jmeter.apache.org/download_jmeter.cgi 目前最新版为2.9,其余文件如源代码等也可从如下官网下载 ...
- WPF笔记(2.7 文字布局)——Layout
原文:WPF笔记(2.7 文字布局)--Layout 这一节介绍的是文字布局的几个控件:1.TextBlock 最基本的文字控件可以配置5个Font属性.TextWraping属性,&quo ...
- OpenCV在ARM上的移植
OpenCV在ARM上的移植 与X86 Linux类似,请参考:Linux 下编译安装OpenCV 本文在此基础上进行进一步操作. 网络上很多移植编译的方法比较老,多数针对OpenCV 1.0,而且方 ...
- 【转】ubuntu下putty的复制粘贴 -- 不错
原文网址:http://www.nwber.com/?p=165 今天在ubutnu下想用putty玩玩,突然发现在windows里直接点击右键的复制居然不管用了,调设置也没有用.这可麻烦了,要是手动 ...
- VS2008生成的程序无法在其它电脑上运行,提示系统无法执行指定的程序
经过一番查找,最给力的参考是 http://www.cnblogs.com/visoeclipse/archive/2010/02/27/1674866.html ------------------ ...
- UESTC_Big Brother 2015 UESTC Training for Graph Theory<Problem G>
G - Big Brother Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) ...
- 图的深度优先遍历DFS
图的深度优先遍历是树的前序遍历的应用,其实就是一个递归的过程,我们人为的规定一种条件,或者说一种继续遍历下去的判断条件,只要满足我们定义的这种条件,我们就遍历下去,当然,走过的节点必须记录下来,当条件 ...
- ios8加入通知栏开始
ios8加入通知栏开始 by 吴雪莹 以打开vpn设置为例: @IBAction func open(sender: AnyObject) { let context = self.extension ...
- .NET中的CSV导入导出(实例)
导入代码,从csv文件得到datatable /// <summary> /// Get Data From Csv File /// (Th ...