读书笔记——深入浅出node.js——构建http服务

来源:互联网 发布:linux开机启动应用脚本 编辑:程序博客网 时间:2024/06/04 18:07

朴灵大师的书确实不错,让我受益非浅。

个人理解,仅做参考。

构建http服务

在Web领域,大多编程语言需要专门的Web服务器作为容器,如ASP、ASP.NET需要IIS,PHP需要搭载Apache或Nginx环境,JSP需要Tomcat。而node提供了http模块,基于TCP,内建了HTTP服务,只需几行代码就可构建服务器。如下:

var http = require('http');http.createServer(function(req,res) {  console.log('hello world. req.url = ' + req.url);  res.writeHead(200,{'Content-Type':'text/plain'});  res.end('Hello world\n');}).listen(1337,'127.0.0.1');console.log('Sever running at http://127.0.0.1:1337/');

1、HTTP

启动服务器之后,获取报文

$ curl -v Http://127.0.0.1:1337///第一部分:链接部分* timeout on name lookup is not supported*   Trying 127.0.0.1...  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                 Dload  Upload   Total   Spent    Left  Speed  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 127.0.0.1 (127.0.0.1) port 1337 (#0) //第二部分:链接完成之后,客户端向服务器端发送的请求报文> GET / HTTP/1.1> Host: 127.0.0.1:1337> User-Agent: curl/7.44.0> Accept: */*>//第三部分:服务器端完成处理之后,向客户端发送的响应内容,包括<开头的响应头和输出的Hello world 响应体。< HTTP/1.1 200 OK< Content-Type: text/plain< Date: Sun, 20 Dec 2015 07:21:43 GMT< Connection: keep-alive< Transfer-Encoding: chunked<{ [22 bytes data]100    12    0    12    0     0    750      0 --:--:-- --:--:-- --:--:-- 12000Hello world//第四部分:结束回话* Connection #0 to host 127.0.0.1 left intact

通过报文可以看出HTTP的特点,他是基于请求响应式的,以一问一答的方式实现服务,虽然基于TCP会话,但是本身却没有会话的特点。

  • 从协议的角度来说,现在的应用,如浏览器,其实是一个HTTP代理,用户的行为将通过它转换为HTTP请求报文发送给服务器端,服务器端在处理完请求后,发送响应报文给代理,代理在解析报文之后,将用户需要的内容(通常是报文体)呈现在界面上。*

简而言之,HTTP服务只做两件事:处理HTTP请求,发送HTTP响应。

  • 无论是HTTP请求报文还是HTTP响应报文,都包含:报文头和报文体

2、http模块

HTTP请求

  • 报文第二部分中的报文头通过http_parser进行解析,解析之后为:
 req.method:'GET' req.url: '/' req.httpVersion: 1.1 headers: {//Key : Value 格式    'use-agent': 'curl/7.44.0'    host: '127.0.0.1:1337'    accept: '*/*'    }

此时cookie为:req.headers.cookie
cookie格式为key=value;key2=value形式

什么是Cookie、Session

  • Cookie:HTTP是无状态的协议,但现实中的业务处理需要一定的状态,否者就无法区分不同的用户。比如说无需登录京东就可以添加购物车,你每一次添加的物品(多次请求)都到了同一个购物车。这就需要使用Cookie(存在于报文中)来标识和认证同一个账户。(前后端都可以操作Cookie)
  • Cookie在浏览器和服务器的协作处理分下面几步
    1、服务器向浏览器发送Cookie
    2、浏览器将Cookie保存
    3、之后每次浏览器都会想服务器发送Cookie
  • Session:由于在前后端都可以操作Cookie,所以有时使用Cookie是不安全的。比如需要更具Cookie中的isVIP字段来判断业务逻辑,但是前端可以篡改它来达到伪造的目的。而Session只保存在后端,对前端不可见,因此对于数据敏感的操作,就需要用到Session。(Session有效期限短)
  • 基于Cookie来实现用户与数据的映射:服务器生成Session口令,传递Cookie,通过Cookie口令与Session口令来实现用户与数据的映射。一旦篡改了Cookie口令,就无法完成映射。并且Session口令过期时间短,之后再生成新的口令,这也是为什么登陆京东一段时间不操作就需要重新登陆。

基础中间件cookie-parser、实现:

var parseCookie = function (cookie) {  var cookies = {};  if(!cookie) {    return cookies;  }  var list = cookie.split(';');  for (var i = 0; i < list.length; i++) {    var pair = list[i].split('=');    cookies[pair[0].trim()] = pair[1];  }  return cookies;}//挂载到req对象上//req.cookies = parseCookie(req.headers.cookie);
  • 报文体抽象为一个只读对象流,如果业务逻辑需要读取报文体中的数据,需要在数据流结束之后才能操作
function (req,res) {  //console.log(req.headers);  var buffers = [];  req.on('data', function (trunk) {    buffers.push(trunk);  }).on('end', function () {    var buffers = Buffers.concat(buffers);    // TODO    res.end('Hello world');  })}

HTTP响应

  • 报文头:res.setHeader()和res.writeHeader()
    可以调用setHeader进行多次设置,但只有调用了writeHead之后,报头才会写入链接中。
  • 报文体:res.write()和res.end()
    它们的区别在于res.end()会先调用res.write()发送数据,之后通知服务器这次响应结束。,

HTTP服务的事件

3、HTTP客户端

HTTP客户端原理与服务器端相同。HTTP客户端是服务器端服务模型的另一部分,处于HTTP的另一端,在整个报文的参与中,报文头和报文体由它产生。同时http模块提供了一个底层API:http.request(options, connect),用于构建HTTP客户端,如下:

var http = require('http');var options = {  hostname: '127.0.0.1',  port: 1337,  path: '/',  method: 'GET'};var req = http.request(options, function(res) {  console.log('STATUS: ' + res.statusCode);  console.log('HEADERS: ' + JSON.stringify(res.headers));  res.setEncoding('utf8');  res.on('data', function (chunk) {    console.log(chunk);  });});req.end();
  • 开启服务器后运行它,作用相当于 curl -v Http: //127.0.0.1:1337/。

参数请求:

host: 域名或IP 默认localhosthosename: 服务器名称port: 默认 80localAddress:socketPath: Domain套接字路径method: path:headers:auth: Basic认证
1 0
原创粉丝点击