阅读它的目的只有一个:就是想了解客户端与服务端的通信是怎么实现的?
数据的存储是怎么实现的?
数据流通过程中遇到什么问题、返回什么状态、该怎么解决?
- 网络基础 TCP / IP
- 通常使用的网络是在TCP/IP协议族的基础上运作的,而HTTP只是它内部的一个子集(如果想了解TCP/IP协议族的知识,请问Goole或度娘)。
- 分层管理,分层传输,客户端与服务端通过分层顺序进行通信,客户端从应用层往下走至服务端接收(请求过程)返过来也可以;
-
客户端 : HTTP客户端 (应用层) -> TCP (传输层) -> IP (网络层) -> 网络 (链路层)
|
服务端 : HTTP服务端 (应用层) <- TCP (传输层) <- IP (网络层) <- 网络 (链路层)
- 理解这个图的含义:客户端向服务端发出一个搜索某个数据的HTTP请求,为了传输方便,在传输层(TCP协议)把从应用层上收到的数据进行分割,并在各个报文上打上标记,端口号之类的,然后转发给网络层;在IP协议的网络层,指定目的地MAC地址;然后发往网络。至此,客户端的请求就准备齐全了。然后服务端接收到数据之后层层上报,一直到服务端的应用层,才算是真真接收到客户端传过来的数据请求。
-
- 负责传输的IP协议
- IP协议的作用是把各种数据包传给对方。而传送给对方需要满足一些条件,比如对方的IP地址、MAC地址(MAC地址就是网卡的固定地址)等,IP地址可以设置更换,而MAC地址基本不会更改。
- IP的通信依赖MAC地址。
- IP协议与IP地址
- 负责分割数据包的TCP协议
- 为了更容易的传输大数据,确保数据能够到达目标,TCP采用三次握手的分割数据方法把数据包送出去
- 负责域名解析的DNS服务
- DNS,提供域名到IP地址之间的解析服务,它是通过域名查找IP地址,或者是通过IP地址反查域名
- URI 与 URL
- URI 统一资源标识符,在HTTP协议里,URI就是:http
- URL 资源的地点,URL是URI的子集,在充分理解URI的基础上,也可以使用URL替换URI
- URI的格式
- URI标识符 http
- 登陆认证信息 可选项
- 服务器地址 devapi.jiaj.com.cn
- 服务端端口 8080
- 带层次的文件地址 jiajian-service-cms/api/v1/posts/friend/search
- 查询字符串 ?createUserName=&startTime=&endTime=&page=1&size=10
- 示例:http://devapi.jiaj.com.cn:8080/jiajian-service-cms/api/v1/posts/friend/search?createUserName=&startTime=&endTime=&page=1&size=10
- 简单的HTTP协议
- 通过请求和响应交换达成通信,客户端先发出请求,服务端收到请求后,作出响应,最后返回响应状态
- 客户端请求格式:请求方法(GET / POST / DELETE / PUT) + 请求URI + 协议版本 + 请求首部字段(可选) + 请求实体
- 服务端响应格式:协议版本 + 状态码 + 状态码状态 + 响应首部状态(可选) + 返回实体
- http是不保存状态的,不会持久保存上一次请求或响应的内容。如果需要比较久的保存这个客户端的请求状态、服务器的响应状态,就需要使用Cookie功能
- 如果不是访问特定的资源,而是对服务器本身发起请求,需要用 * 号来代替URI: OPTIONS * HTTP / 1.1
- 告知服务器意图的方法,就是客服端的请求方法:(增,删,改,查)
- GET 获取数据 用作查询 服务器响应返回状态
- POST 向服务端传输数据实体 用作新增、修改
- PUT 传输文件 同FTP,这个方法自身不带验证机制,存在安全问题,不建议使用
- HEAD 用作查询 获取请求报文的首部
- DELETE 删除数据 按请求URI删除指定的资源
- OPTIONS 向服务器询问支持什么方法,服务器返回,支持的方法
- TRACE 追踪路径 客户端通过TRACE方法可以查询发送过去的请求是怎么被加工修改的。这个方法容易引发跨站追踪攻击,不建议使用
- CONNECT 要求与代理服务器通信时,实现用遂道协议进行TCP通信 格式: CONNECT 代理服务器名:端口号 HTTP版本
- HTTP1.0 与 HTTP1.1 支持的方法:
- GET 获取数据资源
- POST 传输数据实体
- DELETE 删除指定数据
- PUT 传输文件
- HEAD 获取报文首部
- OPTIONS 询问支持方法
- TRACE 追踪路径
- CONNECT 要求用遂道协议连接代理
- 持久连接:
HTTP 1.1 中,所有的连接默认都是持久连接。HTTP 1.0没有实现。
服务端不一定能够实现持久连接;
客户端需要持久连接;
- 使用Cookie,进行状态管理
- Cookie技术是通过在请求和响应报文中写入cookie信息来控制客户端的状态
- Cookie的使用,它的交互:
- 请求(这时没有cookie信息):GET
- 响应(服务端生成cookie信息): 200 OK
- 再次请求(自动发送保存着的Cookie信息) :GET
- 设置cookie: http://www.cnblogs.com/xiaochaohuashengmi/archive/2010/06/13/1757658.html
- cookie知识: http://blog.csdn.net/fangaoxin/article/details/6952954
- cookie运行原理:Cookie 会根据服务端发送的响应报文内的一个叫做 setCookie() 通知客户端保存 cookie。当客户端再向服务器发送请求时,这个请求会自动加入cookie。当服务端接收到客户端发来的带cookie的请求后,服务端会检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之间的状态信息。
- cookie 不提供修改、删除。如果要修改某个cookie,只需要新建一个同名的cookie,添加到response中覆盖原来的Cookie
- 设置cookie方法:
-
第一种方法: <script> //设置cookie function setCookie(cname, cvalue, exdays) { var d = new Date(); d.setTime(d.getTime() + (exdays*24*60*60*1000)); var expires = "expires="+d.toUTCString(); document.cookie = cname + "=" + cvalue + "; " + expires; } //获取cookie function getCookie(cname) { var name = cname + "="; var ca = document.cookie.split(';'); for(var i=0; i<ca.length; i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1); if (c.indexOf(name) != -1) return c.substring(name.length, c.length); } return ""; } //清除cookie function clearCookie(name) { setCookie(name, "", -1); } function checkCookie() { var user = getCookie("username"); if (user != "") { alert("Welcome again " + user); } else { user = prompt("Please enter your name:", ""); if (user != "" && user != null) { setCookie("username", user, 365); } } } checkCookie(); </script>
第二种方法: <script> //JS操作cookies方法! //写cookies function setCookie(c_name, value, expiredays){ var exdate=new Date(); exdate.setDate(exdate.getDate() + expiredays); document.cookie=c_name+ "=" + escape(value) + ((expiredays==null) ? "" : ";expires="+exdate.toGMTString()); } //读取cookies function getCookie(name) { var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); if(arr=document.cookie.match(reg)) return (arr[2]); else return null; } //删除cookies function delCookie(name) { var exp = new Date(); exp.setTime(exp.getTime() - 1); var cval=getCookie(name); if(cval!=null) document.cookie= name + "="+cval+";expires="+exp.toGMTString(); } //使用示例 setCookie('username','Darren',30) alert(getCookie("username")); </script>
例子: <html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <head> <script language="JavaScript" type="text/javascript"> function addCookie(objName, objValue, objHours){//添加cookie var str = objName + "=" + escape(objValue); if (objHours > 0) {//为0时不设定过期时间,浏览器关闭时cookie自动消失 var date = new Date(); var ms = objHours * 3600 * 1000; date.setTime(date.getTime() + ms); str += "; expires=" + date.toGMTString(); } document.cookie = str; alert("添加cookie成功"); } function getCookie(objName){//获取指定名称的cookie的值 var arrStr = document.cookie.split("; "); for (var i = 0; i < arrStr.length; i++) { var temp = arrStr[i].split("="); if (temp[0] == objName) return unescape(temp[1]); } } function delCookie(name){//为了删除指定名称的cookie,可以将其过期时间设定为一个过去的时间 var date = new Date(); date.setTime(date.getTime() - 10000); document.cookie = name + "=a; expires=" + date.toGMTString(); } function allCookie(){//读取所有保存的cookie字符串 var str = document.cookie; if (str == "") { str = "没有保存任何cookie"; } alert(str); } function $(m, n){ return document.forms[m].elements[n].value; } function add_(){ var cookie_name = $("myform", "cookie_name"); var cookie_value = $("myform", "cookie_value"); var cookie_expireHours = $("myform", "cookie_expiresHours"); addCookie(cookie_name, cookie_value, cookie_expireHours); } function get_(){ var cookie_name = $("myform", "cookie_name"); var cookie_value = getCookie(cookie_name); alert(cookie_value); } function del_(){ var cookie_name = $("myform", "cookie_name"); delCookie(cookie_name); alert("删除成功"); } </script> </head> <body> <form name="myform"> <div> <label for="cookie_name"> 名称 </label> <input type="text" name="cookie_name" /> </div> <div> <label for="cookie_value"> 值 </lable> <input type="text" name="cookie_value" /> </div> <div> <label for="cookie_expireHours"> 多少个小时过期 </lable> <input type="text" name="cookie_expiresHours" /> </div> <div> <input type="button" value="添加该cookie" onclick="add_()"/><input type="button" value="读取所有cookie" onclick="allCookie()"/><input type="button" value="读取该名称cookie" onclick="get_()"/><input type="button" value="删除该名称cookie" onclick="del_()"/> </div> </form> </body> </html>
-
- 报文主体和实体主体的差异
- 报文:message
- 实体:entity
通常,报文主体 == 实体主体。只有当传输进行编码时,实体主体内容发生变化,才会导致报文主体产生差异。
- 压缩传输内容
HTTP 协议中有一种被称为内容编码的功能也能进行类似的操作。这个编码功能是应用在实体上的,并保持实体原样压缩。编码后的实体由客户端接收并负责解码。
常用的内容编码有:
- gzip(Gnu zip);
- compress
- deflate(zlib)
- identity(不进行编码)
获取指定范围的请求(断点续传功能),指定范围发送的请求:
执行范围请求时,会用到首部字段 Range 来指定资源的 byte 范围:如
从5000 ~ 10000 字节:
Range: bytes = 5000 - 10000;
5000以后的全部字节:
Range: bytes = 5000 -;
从一开始到3000字节,和5000~7000字节
Range: bytes = -3000, 5000 - 7000;
- HTTP 状态码,是http请求返回结果的标记、服务端处理是否正常、通知出现的错误:
- 1XX Informational 信息状态码,表示:接收的请求正在处理;
- 2XX Success 成功状态码,表示:请求正常处理完毕;
- 3XX Redirection 重定向状态码,表示:需要进行附加操作以完成请求;
- 4XX Client Error 客户端错误状态码,表示:服务器无法处理请求;
- 5XX Server Error 服务器错误状态码,表示:服务器处理请求出错;
常用状态码:
2XX 成功 向服务器请求成功;
- 204 表示:服务器接收的请求已成功处理,但没有资源返回;
- 206 表示:客户端进行了范围请求,服务端已经成功执行了这个请求;
- 200 表示:客户端请求成功;
3XX 重定向 浏览器需要执行某些特殊的处理。当301、302、303响应状态码返回时,几乎所有的浏览器都会把post改成get,并删除报文主体,之后请求会自动发送。
- 301 永久性重定向 表示请求的资源巳被重新分配了URI,希望用户能使用新的URI访问
- 302 临时重定向 表示请求的URI资源巳临时定位到其它位置了,希望用户能使用新的URI访问
- 303 与302有着相同的功能,但303明确表示客户端应采用GET方法
- 304 附带条件请求时,它和重定向没有任何关系
4XX 客户端错误
- 400 请求方法错误或请求参数错误
- 401 请求需要通过http验证token
- 403 请求被服务器拒绝,未获取访问服务器的授权
- 404 服务器上无法找到请求的资源
5XX 服务端错误
- 500 服务端错误
- 503 服务器暂时处于超负荷状态,无法进行请求
- 单台虚拟主机实现多个域名
- 通信数据转发程序:
- 代理:有转发功能的应用程序
- 网关:它自己没有资源,通过网关提交的请求,这个请求资源是网关从其它服务器转发过来的,它具有转发其它服务器资源的功能
- 隧道:相隔很远的服务器与客户端进行中转
- Cookie
- Cookie是管理服务端与客户端之间的状态,它的工作机制是用户识别以及状态管理。
- 目前使用最广泛的Cookie标准不是RFC(网景公司)中定义的任何一个。
- Cookie的首部字段,说明首部类型 Set-Cookie开始状态管理所使用的Cookie信息响应
- Set-Cookie: 键值对的格式
-
NAME = VALUE
Set-Cookie: status = enable; 打开状态 expires = Tue, 05 Jul 2011 07:26:31 GMT; Cookie的有效期 path = /; 服务器上的文件目录 domain = www.baidu.com; 对象的域名,若不指定,则默认为创建Cookie的服务器域名 - expires 属性,指浏览器可发送cookie的有效期。一旦 Cookie从服务器端发送至客户端,服务器端就不存在可以显式的删除Cookie的方法。但可以通过覆盖巳过期的Cookie,实现对Cookie实质性的删除。
- path 属性,Cookie的path属性可用于限制指定Cookie的发送范围的文件目录。
- domain 属性,通过Cookie的domain属性指定域名可做到与结尾匹配一致。因此,不指定具体的域名,也就是不定的domain属性显示得安全。
- secure 属性,用于限制WEB页面仅在HTTPS安全链接时,才可以发送cookie。
-
Set-Cookie: name = value; secrue
当省略 secrue 属性时,不论HTTP还是HTTPS,都会对Cookie进行回收。
-
- HttpOnly 属性,是Cookie的扩展功能,它使javascript无法获取 Cookie。其目的主要是防止跨站攻击。
-
Set-Cookie: name = value; HttpOnly
通常从web页面可以读取cookie。如果使用这个属性,在使用javascritp的 document.cookie 就无法读取Cookie了
-
- Cookie: status = enable 这是cookie的首部字段,目的是告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie.
- Cookie 最常用的首部字段:
- X-Frame-Options
X-Frame-Options: DENY
- X-Frame-Options
-
- 确保web安全的 https
- 使用HTTPS通信机制可以有效地防止这些问题。
- HTTP的缺点:
- 通信使用明文,不加密,内容可能会被窃听;
- 不验证通信方的身份,因此有可能遭到伪装;
- 无法证明报文的完整性,有可能巳遭篡改;
- HTTP的抓包工具:
- Wireshark:它可以获取HTTP协议的请求和响应的内容,并对其进行解析。像查看GET请求,并查看HTTP报文内容都可以做到。
- HTTPS 是身披SSL外壳的HTTP
- HTTPS并非是应用层的一种新协议,只是HTTP通信接口部分用SSL和TLS协议代替而巳。通常,HTTP直接和TCP通信。当使用SSL时,则演变成先和SSL通信,再由SSL和TCP通信。所以这个HTTPS(SSL),最后的这个S就是指 SSL.
- 采用SSL,HTTP就拥有了HTTPS加密、证书和完整性保护。这些功能。
- SSL是独立的。除了HTTP,其它应用层,比如SMTP 和 Telnet等协议均可配合 SSL 协议使用。
- SSL是当前世界上使用最广泛的网络安全技术。
这本书,断断续续的看了一个月,了解了一下我比较关注的几个知识点,还需要进一步的加深阅读层次。