请求解析
请求方法在报文的第一行,路径在其后
> GET /path?foo=bar HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5
> Host: 127.0.0.1:1337
> Accept: */*
HTTP_Parser在解析时,把报文头的方法取出来设置为req.method,把路径设置为req.url.根据路径进行业务处理的通常有静态文件服务器,选择控制器(/controller/action/a/b/c)
查询字符串
:位于路径?之后,可用node提供的querystring处理,也可用url模块,url.parse(req.url,true).query
如果查询字符串的键出现多次,它的值会变成数组
Cookie
- 记录状态
- 服务端先向客户端发送cookie,浏览器保存,之后每次请求都会带上它
构造cookie
|
|
HTTP_Parser会把cookie解析到req.headers.cookie上,格式为key=value;keys=value2
|
|
发送cookie通过响应报文:Set-Cookie: name=value; Path=/; Expires=Sun, 23-Apr-23 09:01:35 GMT; Domain=.domain.com;
- path cookie使用的路径,路径不满足不会发送
- Expires 过期时间 Max-Age 多久后过期 不设置的话关闭浏览器cookie就丢失
- HttpOnly 不可过脚本document.cookie修改
- secure 只对https生效
|
|
res.setHeader的第二个参数可以是数组以设置多个字段 res.setHeader(‘Set-Cookie’, [serialize(‘foo’, ‘bar’), serialize(‘baz’, ‘val’)]);并且在头部形参两条Set-Cookie
|
|
cookie对性能的影响
- 客户端每次请求都会带上服务端发给它cookie,只要路径匹配
- 减少cookie的大小
- 为静态组件使用不同的域名 静态文件一般不关心状态,用不到cookie,不同的域名cookie不匹配就不会发送,同时也可突破浏览器下载线程数限制
- 减少DNS查询 上面的修改会增加dns查询,但浏览器有dns缓存
session
因为cookie会被前端修改,不安全并且体积大影响性能。而session的数据只保存在服务端,保障数据安全性,也不用每次传递。session会设置有效期且较短,通常20分钟,即此时间内客户端会与服务端交换,session就删掉了
需要解决将用户和服务器的session对应
基于cookie实现用户和数据映射
- 将口令(session_id)放在cookie与服务端数据映射
|
|
- 通过查询字符串来让客户端和服务端对应(链接带key)
|
|
session与安全
对session用私钥加密
- 随机产生口令值可能被命中,并用此套用服务端数据
在服务端设定私钥,用私钥对口令加密
|
|
xxs漏洞
- 跨站脚本攻击 Access-Control-Allow-Origin
这个前端脚本会获取页面的url,$(‘#box’).html(location.hash.replace(‘#’, ‘’));攻击者可以把脚本藏在链接后http://a.com/pathname#,再对url压缩。用户打开后脚本会执行,攻击者可以用此获取cookie来伪装用户甚至管理员
缓存
- 让浏览器缓存静态资源
- 通常只适应于get请求
一开始本地没有文件,浏览器直接请求服务端并将文件缓存,二次请求时若不能确定是否可用,会发起条件请求,在get中附带If-Modified-Since字段
使用时间戳
|
|
服务端如果没有新版本就只需要响应304,浏览器就会使用本地文件;若更新就发送新文件,让浏览器更新缓存
|
|
缺点:时间戳改动内容不一定改,只能精确到秒,更新频繁的内容可能不生效
ETag(Entity Tag)
- 服务端确定生成规则生成
- 请求字段为If-None-Match/ETag
|
|
Expires,Cache-Control
- 让浏览器明确缓存
|
|
http1.0不支持max-age,所以要同时设置Expires,Cache-Control,在浏览器中max-age优先级高于Expires
清除缓存
- 浏览器是根据url进行缓存的,内容更新时可以让浏览器发起新的url缓存
每次发布在路径中跟随文件内容的hash,http://url.com/?hash=afadfadwe.这样能避免无意义的更新
Basic认证
- 通过用户名和密码实现的身份认证
当页面需要Basic认证时,会检查请求头部的Authorization字段,它的值由认证方式和加密值构成
$ curl -v "http://user:pass@www.baidu.com/"
> GET / HTTP/1.1
> Authorization: Basic dXNlcjpwYXNz
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5
> Host: www.baidu.com
> Accept: */*
它会将用户名和密码组合,再Base64编码
|
|
缺点
: 对于密码字段没有加密,只能在https下才能用,但几乎所有浏览器都支持。RFC 2069对它做了改进