[TOC]
## http是tcp的超集
当浏览器请求一个url资源的时候,先和目标服务器建立tcp长连接,然后再发送http请求。(这意味着tcp链接建立完成之前,http请求并没有发送)

可以看到,这里connection先于request触发
### 若http服务器没有res.end(),即不会断开连接

#### end先于close

### Q
#### http只是基于tcp的包装?还是不同于tcp的另一个链接请求?
#### request是第一次发数据的时候才触发吗?
答:只要客户端向服务器发送消息,每次都会触发request事件
#### 发消息就等于客户端链接吗?
不等于,先建立链接才会发送http请求
## 利用curl发送http请求
下图中“相应信息”应为“响应信息”
**注意**:-X的x为大写,post也必须为大写

### 请求报文
请求行 method url protocol
请求头
空白行
请求体


### 响应报文
响应行 protocol statusCode statusDesc
响应头
空白行
响应体



## 创建一个http服务器
```
let http = require('http');
let server = http.createServer(function(req,res){
}).listen(8080,function(){
console.log('server is running on the localhost:8080');
});
```
### req
req代表客户端的一个请求。
server服务器把客户端的请求进行解析,然后放在req对象上。
#### 通过req.x的方式获取请求行和请求头

#### req对象中拿不到hash

#### url.parse(req.url) 获取 url对象
```
import url = require('url'); //url为nodeJS中内置的模块,但需要引用
```

##### req.url和url对象的比较
其中`path`为路径,`pathname`为path去掉`query`的部分
path即是 url从域名后面‘/’及其以后的部分

##### url对象中的query,以及其他

#### 从req中获取请求体
我们不能直接通过req.data的形式拿到请求数据,但!
因为req是一个可读流,可以通过监听"data"事件来获取请求体数据
**注意**:默认拿到的数据为buffer(一段16进制的类数组数据),需要toString

### res
res代表响应,如果希望向客户端回应消息,需要通过res
#### 设置响应行和响应头
statusCode:设置了Code会自动生成对应的描述
sendDate:设置是否在响应中显示响应开始发送的时间
setHeader:设置响应头
removeHeader:移除响应头
getHeader:获取响应头

#### writeHead,可以将状态码和响应头一起写了
headersSent:响应头是否已经发送

这个api存在的意义?
当调用write时响应头就已经发送出去了
为什么调用write就发送了呢? 客户端这时就开始接收数据了,需要知道接收的数据长撒样
这里需要注意的是
而这时可能服务器还准备传点什么给客户端,还没有res.end链接还没有挂断,

**注意**:
1. 如果是调用write而不是直接调用end,这里会分块传输 见上图【Transfer-Encoding】
2. 如果响应时没有end,也不会在响应头中出现【Content-Length】这个属性
3. 这里分块传输的时候字节数比应该的多,是因为:
分块编码相当简单,在头部加入 Transfer-Encoding: chunked 之后,就代表这个报文采用了分块编码。这时,报文中的实体需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的 CRLF(\r\n),也不包括分块数据结尾的 CRLF。最后一个分块长度值必须为 0,对应的分块数据没有内容,表示实体结束。
相关文章: https://www.cnblogs.com/simonbaker/p/5593177.html
### 创建http服务器的第二种形式
```
let server = http.createServer();
server.on('connection',function(socket){
});
server.on('request',function(req,res){
});
server.listen(8080,function(){
console.log('server started at http://localhost:8080')
});
```