设为首页 收藏本站
查看: 1040|回复: 0

[经验分享] 大熊君大话NodeJS之------Http模块

[复制链接]

尚未签到

发表于 2017-2-22 11:24:42 | 显示全部楼层 |阅读模式
  一,开篇分析
  首先“Http”这个概念大家应该比较熟悉了,它不是基于特定语言的,是一个通用的应用层协议,不同语言有不同的实现细节,但是万变不离其宗,思想是相同的,
  NodeJS作为一个宿主运行环境,以JavaScript为宿主语言,它也有自己实现的一套标准,这篇文章我们就一起来学习一下 “Http模块” 。但是作为前提来说,
  希望大家可以先阅读一下官网提供的api,有一个前置了解,这样就方便多了,以下是Http部分的api概览:



HTTP
http.STATUS_CODES
http.createServer([requestListener])
http.createClient([port], [host])
Class: http.Server
事件 : 'request'
事件: 'connection'
事件: 'close'
Event: 'checkContinue'
事件: 'connect'
Event: 'upgrade'
Event: 'clientError'
server.listen(port, [hostname], [backlog], [callback])
server.listen(path, [callback])
server.listen(handle, [callback])
server.close([callback])
server.maxHeadersCount
server.setTimeout(msecs, callback)
server.timeout
Class: http.ServerResponse
事件: 'close'
response.writeContinue()
response.writeHead(statusCode, [reasonPhrase], [headers])
response.setTimeout(msecs, callback)
response.statusCode
response.setHeader(name, value)
response.headersSent
response.sendDate
response.getHeader(name)
response.removeHeader(name)
response.write(chunk, [encoding])
response.addTrailers(headers)
response.end([data], [encoding])
http.request(options, callback)
http.get(options, callback)
Class: http.Agent
new Agent([options])
agent.maxSockets
agent.maxFreeSockets
agent.sockets
agent.freeSockets
agent.requests
agent.destroy()
agent.getName(options)
http.globalAgent
Class: http.ClientRequest
Event 'response'
Event: 'socket'
事件: 'connect'
Event: 'upgrade'
Event: 'continue'
request.write(chunk, [encoding])
request.end([data], [encoding])
request.abort()
request.setTimeout(timeout, [callback])
request.setNoDelay([noDelay])
request.setSocketKeepAlive([enable], [initialDelay])
http.IncomingMessage
事件: 'close'
message.httpVersion
message.headers
message.rawHeaders
message.trailers
message.rawTrailers
message.setTimeout(msecs, callback)
message.method
message.url
message.statusCode
message.socket

  让我们先从一个简单例子开始,创建一个叫server.js的文件,并写入以下代码:



1 var http = require('http') ;
2 var server = http.createServer(function(req,res){
3 res.writeHeader(200,{
4     'Content-Type' : 'text/plain;charset=utf-8'  // 添加charset=utf-8
5 }) ;
6 res.end("Hello,大熊!") ;
7 }) ;
8 server.listen(8888) ;
9 console.log("http server running on port 8888 ...") ;
  (node server.js)以下是运行结果:


DSC0000.jpg

  二,细节分析实例
  具体看一下这个小例子:
  (1行):通过"require"引入NodeJS自带的"http"模块,并且把它赋值给http变量。
  (2行):调用http模块提供的函数:"createServer" 。这个函数会返回一个新的web服务器对象。
    参数 "requestListener" 是一个函数,它将会自动加入到 "request" 事件的监听队列。
    当一个request到来时,Event-Loop会将这个Listener回调函数放入执行队列, node中所有的代码都是一个一个从执行队列中拿出来执行的。
    这些执行都是在工作线程上(Event Loop本身可以认为在一个独立的线程中,我们一般不提这个线程,而将node称呼为一个单线程的执行环境),
    所有的回调都是在一个工作线程上运行。
    我们在再来看一下"requestListener"这个回调函数,它提供了两个参数(request,response),
    每次收到一个请求时触发。注意每个连接又可能有多个请求(在keep-alive的连接中)。
    "request"是http.IncomingMessage的一个实例。"response"是http.ServerResponse的一个实例。
    一个http request对象是可读流,而http response对象则是可写流。
  一个"IncomingMessage"对象是由http.Server或http.ClientRequest创建的,
    并作为第一参数分别传递给"request"和"response"事件。
    它也可以被用来访问应答的状态,头文件和数据。
    它实现了 "Stream" 接口以及以下额外的事件,方法和属性。(具体参考api)。

  (3行):“writeHeader”,使用 "response.writeHead()" 函数发送一个Http状态200和Http头的内容类型(content-type)。
    向请求回复响应头。"statusCode"是一个三位是的HTTP状态码,例如 404 。最后一个参数,"headers",是响应头的内容。
    举个栗子:



1 var body = 'hello world' ;
2 response.writeHead(200, {
3      'Content-Length': body.length,
4      'Content-Type': 'text/plain'
5 }) ;
   注意:Content-Length 是以字节(byte)计算,而不是以字符(character)计算
  之前的例子原因是字符串 “Hello World !” 只包含了单字节的字符。
  如果body包含了多字节编码的字符,就应当使用Buffer.byteLength()来确定在多字节字符编码情况下字符串的字节数。
  需要进一步说明的是Node不检查Content-Lenth属性和已传输的body长度是否吻合。
  statusCode是一个三位是的HTTP状态码, 例如:"404" 。这里要说的是 "http.STATUS_CODES" ,全部标准"Http"响应状态码的集合和简短描述都在里面。
   如下是源码参考:
    



1 var STATUS_CODES = exports.STATUS_CODES = {
2   100 : 'Continue',
3   101 : 'Switching Protocols',
4   102 : 'Processing',                 // RFC 2518, obsoleted by RFC 4918
5   200 : 'OK',
6   201 : 'Created',
7   202 : 'Accepted',
8   203 : 'Non-Authoritative Information',
9   204 : 'No Content',
10   205 : 'Reset Content',
11   206 : 'Partial Content',
12   207 : 'Multi-Status',               // RFC 4918
13   300 : 'Multiple Choices',
14   301 : 'Moved Permanently',
15   302 : 'Moved Temporarily',
16   303 : 'See Other',
17   304 : 'Not Modified',
18   305 : 'Use Proxy',
19   307 : 'Temporary Redirect',
20   400 : 'Bad Request',
21   401 : 'Unauthorized',
22   402 : 'Payment Required',
23   403 : 'Forbidden',
24   404 : 'Not Found',
25   405 : 'Method Not Allowed',
26   406 : 'Not Acceptable',
27   407 : 'Proxy Authentication Required',
28   408 : 'Request Time-out',
29   409 : 'Conflict',
30   410 : 'Gone',
31   411 : 'Length Required',
32   412 : 'Precondition Failed',
33   413 : 'Request Entity Too Large',
34   414 : 'Request-URI Too Large',
35   415 : 'Unsupported Media Type',
36   416 : 'Requested Range Not Satisfiable',
37   417 : 'Expectation Failed',
38   418 : 'I\'m a teapot',              // RFC 2324
39   422 : 'Unprocessable Entity',       // RFC 4918
40   423 : 'Locked',                     // RFC 4918
41   424 : 'Failed Dependency',          // RFC 4918
42   425 : 'Unordered Collection',       // RFC 4918
43   426 : 'Upgrade Required',           // RFC 2817
44   500 : 'Internal Server Error',
45   501 : 'Not Implemented',
46   502 : 'Bad Gateway',
47   503 : 'Service Unavailable',
48   504 : 'Gateway Time-out',
49   505 : 'HTTP Version not supported',
50   506 : 'Variant Also Negotiates',    // RFC 2295
51   507 : 'Insufficient Storage',       // RFC 4918
52   509 : 'Bandwidth Limit Exceeded',
53   510 : 'Not Extended'                // RFC 2774
54 };
  节选自,Nodejs源码 ”http.js“ 143行开始。
  其实从客户端应答结果也不难看出:
DSC0001.png

  (6行):”response.end“------当所有的响应报头和报文被发送完成时这个方法将信号发送给服务器。服务器会认为这个消息完成了。
    每次响应完成之后必须调用该方法。如果指定了参数 “data” ,就相当于先调用  “response.write(data, encoding) ” 之后再调用 “response.end()” 。
  (8行):”server.listen(8888)“ ------ 服务器用指定的句柄接受连接,绑定在特定的端口。
  以上就是一个比较详细的分析过程,希望有助于加深理解,代码虽然不多,但是重在理解一些细节机制,以便日后高效的开发NodeJS应用。
  三,实例赏心
  除了可以使用"request"对象访问请求头数据外,还能把"request"对象当作一个只读数据流来访问请求体数据。
  这是一个"POST"请求的例子:



1 http.createServer(function (request, response) {
2     var body = [];
3     console.log(request.method) ;
4     console.log(request.headers) ;
5     request.on('data', function (chunk) {
6         body.push(chunk);
7     }) ;
8     request.on('end', function () {
9         body = Buffer.concat(body) ;
10         console.log(body.toString()) ;
11     });
12 }).listen(8888) ;
  下是一个完整的“Http”请求数据内容。



1 POST / HTTP/1.1
2 User-Agent: curl/7.26.0
3 Host: localhost
4 Accept: */*
5 Content-Length: 11
6 Content-Type: application/x-www-form-urlencoded
7 Hello World
  四,总结一下
  (1),理解 "Http" 概念。
  (2),熟练使用 "Http" 相关的api。
  (3),注意细节的把控,比如:“POST,GET” 之间的处理细节。
  (4),"requestListener"的理解。
  (5),强调一个概念:一个http request对象是可读流,而http response对象则是可写流 。

   哈哈哈,本篇结束,未完待续,希望和大家多多交流够沟通,共同进步。。。。。。呼呼呼……(*^__^*)        

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-345686-1-1.html 上篇帖子: [nodejs]使用神器webstorm调试nodejs 下篇帖子: Nodejs之MEAN栈开发(一)---- 路由与控制器
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表