HTTP
…
概述
参考网站:MDN
一个完整的HTTP请求:
- Redirect - 根据本地缓存判断,是否永久跳转到新的URL
- App cache - 查询资源缓存
- DNS - DNS 解析域名
- TCP - 创建TCP,SSL
- Request - 请求
- Response - 响应
版本
- 1.1
- 持久TCP连接
- Pipeline 多个请求放入一个Pipeline依次处理
- Host等命令,区分服务器上的不同web服务
- 2
- 所有数据以二进制传输
- 多个请求不再按照顺序处理
- 头信息压缩
- 服务器主动推送
如果客户端想要升级协议,例如:HTTP/2, WebSocket
,可以配置头部:
1 | GET /index.html |
资源
HTTP 资源
- URI - 包含 URL 和 URN - 统一资源标识符
- URL - 统一资源定位符
- protocol://user:password@hostname:port/path?query=string#hash
- URN - 永久统一资源定位符 - 目前还没有成熟方案
URL 模式
- 普通模式 - 使用
?
携带参数,/app?id=1&name=xyz
- PATHINFO - 使用
/
,-
携带参数/index.php/module/action/var
/index.php/module-action-var
- REWRITE - 在PATHINFO基础上增加了重写规则,可以去掉
index.php
- 兼容模式 - 用于不支持PATHINFO的情况,
/index.php/?s=/module/action/var
Data URL:允许向文档中嵌入小文件,其格式如下:
1 | data:[<mediatype>][;base64],<data> |
MIME 类型:用于描述文件类型。
- text / plain, html, css, javascript - 文本
- image / gif, png, jpg, bmp, x-icon … - 图片
- application / xml, pdf, javascript, x-www-form-urlencoded, json - 二进制文件
- multipart / form-data, byteranges - 复合文件格式,
- 例:
byteranges
可以配合206
来发送文件的一部分
- 例:
- audio / midi, mpeg, ogg, wav
- video / webm, ogg
- font
- message
- example
- model
HTTP客户端 CURL
1 | # 一次访问 |
客户端由user-agent
描述。
CORS 跨域
- 请求会接受,响应也会发送,但是会被浏览器拦截响应
- 不受跨域限制的有link, script, img等标签
- 默认只允许
- 方法:GET, HEAD, POST
- Content-Type: text/plain, multipart/form-data, application/x-www-form-urlencoded
- 请求头:Accept, Accept-Language, Content-Language, Content-Type
- XMLHttpRequestUpload 对象,均没有注册任何事件监听器
- 没有ReadableStream对象
- 预请求验证
- 先发送一个OPTIONS请求,再发送真正的请求
- 服务器端的Response需要添加头部
- ‘Access-Control-Allow-Origin’: ‘*’
- 添加允许的请求头
- ‘Access-Control-Allow-Headers’: ‘X-Test-Cors’
- 添加允许的方法
- ‘Access-Control-Allow-Methods’: ‘POST, PUT, DELETE’
- 1000秒内不用再发预请求
- ‘Access-Control-Max-Age’: ‘1000’
缓存
- Cache-Control 字段:客户端的缓存
- 可缓存性:public, private, no-cache
- public - 请求经过的所有节点都可以缓存
- private - 只有发起请求的浏览器可以缓存
- no-cache - 缓存,但是每次去服务器验证一次
- 到期
- max-age = 秒数 - 浏览器使用
- s-maxage = 秒数 - 代理服务器使用
- max-stale = 秒数 - 即便缓存过期,但是没超过这个时间,缓存仍然可以用
- 重新验证
- must-revalidate - 如果已经过期,则必须到原服务端验证缓存
- proxy-revalidate - 代理服务去原服务器验证缓存
- 其他
- no-store - 不缓存,每次去服务器拿新数据
- no-transform - 代理服务器不对数据做改动(压缩等)
- 如果想要每次更新后重新请求缓存,可以通过修改资源名,使用hash名称。
- 资源验证
- Code:304 - 所请求的资源未修改,允许客户端使用缓存
- 验证头
- Last-Modified - ‘123’ - 对比时间,过期则请求缓存
- If-Modified-Since - 客户端下次请求,就会拿出这些头
- If-Unmodified-Since -
- Etag - ‘789’ - 通过数据签名验证,每个数据签名唯一,只要修改就变
- If-Match - 客户端下次请求,就会拿出这些头
- If-Non-Match
- Last-Modified - ‘123’ - 对比时间,过期则请求缓存
1 | // Etag |
Cookie
- Set-Cookie - 服务器设置,之后客户端每次访问都会带着,可以有多个这个头,不可跨域访问
- max-age - 有效时间,默认关闭浏览器后清除
- expires - 到期时间
- Secure
- HttpOnly - 禁止
Javascript
访问 - domain - 允许设置的域名,可以解决跨域不能访问的问题
1 | // Cookie |
但是由于传输Cookie会带来额外开销,因此浏览器又提供了新的数据存储方法。
- sessionStorage - 为每个页面开辟的独立存储区域,浏览器关闭后释放。大小一般为10MB。
- localStorage - 功能相同,关闭浏览器也不会消失。大小一般为10MB。
- IndexedDB - 基于 JavaScript 的非关系数据库,大小可达2GB。可以用于WebGL开发。
身份验证
当客户端未授权访问一个页面时,服务器会返回401 unauthorized
响应,并附带WWW-Authenticate
头部对客户端进行质询,该头部包含了几种允许的质询的方式。之后客户端就会在Authorization
头部写入身份凭证信息。
代理服务器也可以对客户端进行身份验证,使用的是407
响应,并附带Proxy-Authorization
头部。之后客户端就会在Proxy-Authorization
头部写入身份凭证信息。
验证方案有如下集中:
- Basic 基本认证,base64编码用户名和密码(即用户凭证)
- Authorization: Basic base64(user:password)
- Digest 摘要认证,采用质询与响应方法
- Authorization-Required
- WWW-Authenticate: Digest realm=”DIGEST” …(质询码,加密算法,等)
- Authorization: Digest username=”user” realm=”DIGEST” response=”xxx” …(质询码,加密算法,等)
- SSL 客户端认证:利用HTTPS
- FormBase 表单认证:利用Cookie和Session
- Bearer 通过OAuth 2.0保护资源
- HOBA
- Mutual
- AWS4-HMAC-SHA256
长连接
- 并发限制:默认是6个连接,多了会等待
- Connection
- keep-alive - 保持长连接
- close - 关闭长连接
数据协商
- 客户端要求的数据格式,服务器返回的格式
- 请求
- Accept
- Accept-Encoding - 编码方式
- Accept-Language - 语言
- User-Agent - 浏览器信息
- 响应
- Content-Type - 对应 Accept 里的一种格式,使用
MIME Type
- application/x-www-form-urlencoded
- multipart/form-data - 上传文件使用,需要加boundry,不同部分可以是不同的Content-Type
- text/plain
- X-Content-Type-Options - nosniff - 禁止客户端预测返回内容
- Content-Encoding - 数据压缩
- gzip
- Content-Language
- Content-Type - 对应 Accept 里的一种格式,使用
- 断点续传
- Range - 请求头中,指示第一个字节和最后一个字节的位置
- 0-1024, 3000-3999, 8000-
- Content-Range - (200, 206) 响应头,表示返回的实际内容
- bytes 0-1024 /
[总长度]
- bytes 0-1024 /
- Content-Length - 响应头,表示返回的实际长度
- Range - 请求头中,指示第一个字节和最后一个字节的位置
重定向
- 响应 Code:
- 301 - 永久跳转,下次跳转不会经过服务器,慎用
- 302 - 临时跳转
- Location - 新的 URL
- 如果不是同一个域,就需要加上hostname和端口
内容安全策略 CSP
- 用于限制资源获取,报告资源获取越权
- 资源类型限制
- default-src - 全局限制
- connect-src - 请求源限制
- img-src, font-src, frame-src, media-src, style-src, script-src, manifest-src - 可以被哪个网址加载
- Content-Security-Policy:
- default-src http: https:
- 禁用 inline script
- default-src ‘self’
- 禁用 外链资源,只能加载本站资源
- default-src ‘self’ ‘http://www.baidu.com/‘
- 只允许 本站和百度的资源
- form-action ‘self’
- 只允许 表单提交到本站
- report-uri /report
- 问题报告到这个连接
- default-src http: https:
- Content-Security-Policy-Report-Only - 检测到,但是不拦截,只报告
也可以写到htle的meta标签中。
1 | <head> |
HTTPS
客户端向服务端发送请求,服务器返回一个公钥,客户端使用公钥加密数据再次发给服务器,服务器利用私钥解密数据。
此外,CA会向服务器颁发证书,证书中包含:服务器公钥(CA用私钥加密),签名(CA用私钥加密)等。之后服务器只向客户端发送证书,证书的合法性由客户端自己去求证。
TLS/SSL协议:
- SSL 3.0 - 存在安全漏洞
- TLS 1.0 - 存在安全漏洞
- TLS 1.1
- TLS 1.2
- TLS 1.3
使用HTTPS需要证书,以及对于证书的加解密配置。证书可以让CA签发,也可以自己生成。
生成一个证书
1 | # 服务器证书 : alias 别名, keystore 证书存放位置, validity 证书过期时间, sigalg 签名算法 |
WebSocket
过去采用Ajax,Long Poll等方式同步数据。
WebSocket建立时,请求发送协议升级请求,同时给出Websocket-Key,通信协议(chat, superchat),版本号。服务器会返回响应。
HTTP2
SPDY,用于TLS与HTTP之间,用来提速网络。SPDY会多路复用,请求优化。服务器也会主动推送。压缩了HTTP头,强制使用SSL。
HTTP2是基于SPDY设计的。最特色的功能是采用二进制传输而非文本传输,数据采用分帧发送。同时会压缩首部,且双方各维护一份首部表,一般会只发送更新的部分。也采用了多路复用。可以并行交错发送数据。流设置优先级,高优先级的流(css, js)先发送,优先级不是绝对的。服务器还会主动推送,例如主动推送CSS, JS文件。
WebDAV
基于WWW的分布式文件系统。支持在线打开,编辑,映射为本地的硬盘。
HTTP3
基于QUIC协议发展,而QUIC底层使用UDP。HTTP 2.0有队头阻塞,握手延迟大问题。
QUIC不使用(IP, PORT)识别对方,而是采用ID的方式,这在移动端更适用。
QUIC采用前向纠错。
Web 安全
安全问题
- Authentication 验证
- Authorization 授权
- 客户端攻击
- 远程执行
- 信息泄露
- 逻辑问题
漏洞分类
- 注入:SQL NOSQL OS LDAP
- 失效身份验证,破译密码,密钥等
- 敏感数据泄露
- XXE 利用XML外部实体窃取内部文件,执行远程代码
- 失效的访问控制
- 安全配置错误:默认设置,不完整的配置等
- XSS 跨站攻击
- 不安全的反序列化
- 含有漏洞的组件
- 不足的日志记录和监控(必须含有6个月的日志)
安全机制
- 验证机制,登录
- 会话管理,SESSION
- 访问控制,API接口
验证机制
方案:输入用户名密码,使用SSL,限制登录等。
双因子认证:个人密码 + 手机验证码。
忘记密码:需要身份验证。邮箱找回密码,负载要加密。
多阶登录机制并不安全。
会话管理
服务器在用户登录后签发一个令牌,并为令牌签名。
应当适当终止会话,过期Session。
HTTP 状态码
1xx:信息
100 Continue:服务器仅接收到部分请求,但是一旦服务器并没有拒绝该请求,客户端应该继续发送其余的请求。
101 Switching Protocols:服务器转换协议:服务器将遵从客户的请求转换到另外一种协议。
103 Checkpoint:用于 PUT 或者 POST 请求恢复失败时的恢复请求建议。
2xx:成功
200 OK:请求成功(这是对HTTP请求成功的标准应答。)
201 Created:请求被创建完成,同时新的资源被创建。
202 Accepted:供处理的请求已被接受,但是处理未完成。
203 Non-Authoritative Information:请求已经被成功处理,但是一些应答头可能不正确,因为使用的是其他文档的拷贝。
204 No Content:请求已经被成功处理,但是没有返回新文档。浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。
205 Reset Content:请求已经被成功处理,但是没有返回新文档。但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容。
206 Partial Content:客户发送了一个带有Range头的GET请求,服务器完成了它。
3xx:重定向
300 Multiple Choices:多重选择。链接列表。用户可以选择某链接到达目的地。最多允许五个地址。
301 Moved Permanently:所请求的页面已经转移至新的 URL 。
302 Found:所请求的页面已经临时转移至新的 URL 。
303 See Other:所请求的页面可在别的 URL 下被找到。
304 Not Modified:未按预期修改文档。客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。
305 Use Proxy:客户请求的文档应该通过Location头所指明的代理服务器提取。
306 Switch Proxy:目前已不再使用,但是代码依然被保留。
307 Temporary Redirect:被请求的页面已经临时移至新的 URL 。
308 Resume Incomplete:用于 PUT 或者 POST 请求恢复失败时的恢复请求建议。
4xx:客户端错误
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 Timeout:请求超出了服务器的等待时间。
409 Conflict:由于冲突,请求无法被完成。
410 Gone:被请求的页面不可用。
411 Length Required:”Content-Length” 未被定义。如果无此内容,服务器不会接受请求。
412 Precondition Failed:请求中的前提条件被服务器评估为失败。
413 Request Entity Too Large:由于所请求的实体太大,服务器不会接受请求。
414 Request-URI Too Long:由于 URL 太长,服务器不会接受请求。当 POST 请求被转换为带有很长的查询信息的 GET 请求时,就会发生这种情况。
415 Unsupported Media Type:由于媒介类型不被支持,服务器不会接受请求。
416 Requested Range Not Satisfiable:客户端请求部分文档,但是服务器不能提供被请求的部分。
417 Expectation Failed:服务器不能满足客户在请求中指定的请求头。
5xx:服务器错误
500 Internal Server Error:请求未完成。服务器遇到不可预知的情况。
501 Not Implemented:请求未完成。服务器不支持所请求的功能,或者服务器无法完成请求。
502 Bad Gateway:请求未完成。服务器充当网关或者代理的角色时,从上游服务器收到一个无效的响应。
503 Service Unavailable:服务器当前不可用(过载或者当机)。
504 Gateway Timeout:网关超时。服务器充当网关或者代理的角色时,未能从上游服务器收到一个及时的响应。
505 HTTP Version Not Supported:服务器不支持请求中指明的HTTP协议版本。
511 Network Authentication Required:用户需要提供身份验证来获取网络访问入口。