0. HTTP协议概述
HTTP协议(Hyper Text Transfer Protocol,超文本传输协议)是用于网络中客户端和服务端之间通信的应用层协议。底层一般用TCP/IP协议提供可靠连接。HTTP协议采用请求/响应模型,客户端和服务端建立TCP连接后,客户端向服务端发出请求,服务端收到请求后对请求进行处理,把响应发送到客户端。
1. HTTP协议特点
- 基于请求-响应模式
HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并 返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有 接收到请求之前不会发送响应 - 无状态(stateless):
HTTP是一种无状态协议。HTTP协议自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这个级别,协议对于发送过的请求或响应都不做持久化处理。
使用HTTP协议,每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把HTTP协议设计成 如此简单的。可是,随着Web的不断发展,因无状态而导致业务处理变得棘手 的情况增多了。比如,用户登录到一家购物网站,即使他跳转到该站的 其他页面后,也需要能继续保持登录状态。针对这个实例,网站为了能 够掌握是谁送出的请求,需要保存用户的状态。HTTP/1.1虽然是无状态协议,但为了实现期望的保持状态功能, 于是引入了Cookie技术。有了Cookie再用HTTP协议通信,就可以管 理状态了。
- 无连接:
限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间,并且可以提高并发性能,不能和每个用户建立长久的连接,请求一次相应一次,服务端和客户端就中断了。
但是无连接有两种方式,早期的http协议是一个请求一个响应之后,直接就断开了,但是现在的http协议1.1版本不是直接就断开了,而是等几秒钟,如果用户在这几秒钟之内有新的请求,那么还是通过之前的连接通道来收发消息,如果过了这几秒钟用户没有发送新的请求,那么就会断开连接,这样可以提高效率,减少短时间内建立连接的次数,因为建立连接也是耗时的,默认的好像是3秒中现在,但是这个时间是可以通过咱们后端的代码来调整的,自己网站根据自己网站用户的行为来分析统计出一个最优的等待时间。 - 灵活(媒体独立)
HTTP允许传输任意类型的数据。正在传输的类型由Content-Type标记。这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。
2. HTTP之URL
URL(Uniform Resource Locator,统一资源定位符),是互联网上用来标识某一处资源的地址。
http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
- 协议部分:http:代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等等本例中使用的是HTTP协议。在"HTTP"后面的“//”为分隔符
- 域名部分:www.aspxfans.com,可以请求DNS服务器解析域名对应的IP地址,也可以使用IP地址作为域名
- 端口部分:8080,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口
- 虚拟目录部分:/news/,从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。
- 文件名部分:index.asp,从域名后的最后一个“/”开始到“?”为止是文件名部分,文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名
- 锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分
- 参数部分:boardID=5&ID=24618&page=1,从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。多个参数之间用“&”作为分隔符。
原文(http://blog.csdn.net/ergouge/article/details/8185219 )
3. 在浏览器地址栏输入URL,按下回车,经历了什么?
- 浏览器在本地host文件查找URL中域名对应的IP地址,或者向DNS服务器请求解析域名对应的IP地址
- 浏览器根据IP地址和HTTP协议的端口号80建立socket,和服务器建立TCP连接
- TCP连接两次握手后,浏览器把HTTP请求报文作为TCP连接第三次握手的报文数据发送给服务器
- 服务器解析请求报文,对请求进行处理,把html文件放到响应报文里发送给浏览器
- 浏览器收到响应报文后,断开TCP连接
- 浏览器解析响应报文,把页面呈现出来
4. HTTP请求报文和响应报文格式
1.请求报文:包括请求头、请求行、空行和请求数据(请求体)四部分。请求行包括:请求方法 URL 和协议版本
- 响应报文包括状态行、响应头、空行和响应正文。
5. HTTP请求方法
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法
- GET
向指定的资源发出“显式”请求,只用来读取想显式的页面,响应的报文中包含页面信息 - HEAD
和GET一样,都是请求指定的资源,但是返回的响应没有具体的内容,只有报头,响应报文很小,但通过报头可以知道“关于请求的资源”的全部信息 - POST
向指定资源提交数据,请求服务器进行处理(比如提交表单和上传文件),提交的数据放在请求体中。这个请求可能会创建新的资源或者对现有的资源进行修改 - PUT
向指定资源上传最新的内容,最新的数据取代指定文档的内容。 - DELETE
请求服务器删除指定的资源 - TRACE
回显服务器收到的请求,主要用来进行测试或者诊断 - CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。 - OPTIONS
可以查看服务器的性能,使服务器返回指定资源支持的所有HTTP请求的方式。用’*'来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。
6. GET和POST的区别
- GET提交的数据会放到URL后面(用?分割URL和提交的数据,多个参数用&分割,比如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0 %E5%A5%BD),而POST提交的数据放在请求报文的请求体里面(body)
- GET提交的数据对大小有限制(虽然HTTP协议没有对URL长度限制,但是浏览器对URL长度有限制,比如IE浏览器的限制是2083字节(2K+35);而POST方法提交的数据理论上没有大小限制,但实际各个WEB服务器会规定对post提交数据大小进行限制,Apache、IIS6都有各自的配置。
- POST的安全性比GET要高,因为GET提交的数据在浏览器地址栏中或请求行中直接就能看到,比如:通过GET提交数据,用户名和密码将明文出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码,除此之外,使用GET提交数据还可能会造成Cross-site request forgery攻击
- GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值。
7. HTTP状态码
- 1xx:指示消息——请求已被服务器接收,继续处理
- 2xx:成功——请求已成功被服务器接收、理解、并接受
- 3xx:重定向——需要后续操作才能完成这一请求
- 4xx:请求错误——请求含有词法错误或者无法被执行
- 5xx:服务器错误——服务器在处理某个正确请求时发生错误
常见状态码:
200 | OK | 客户端请求成功 |
---|---|---|
400 | Bad Request | 客户端请求有语法错误,不能被服务器所理解 |
401 | Unauthorized | 请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用 |
403 | Forbidden | 服务器收到请求,但是拒绝提供服务 |
404 | Not Found | 请求资源不存在,eg:输入了错误的URL |
500 | Internal Server Error | 服务器发生不可预期的错误 |
503 | Server Unavailable | 服务器当前不能处理客户端的请求,一段时间后可能恢复正常 |
更多状态码:http://www.runoob.com/http/http-status-codes.html
附录
1. 请求头:
Accept:浏览器可接受的MIME类型,用于告诉服务器客户端愿意接受那些内容,比如图像类,办公文档格式等等。;
Accept-Charset:浏览器可接受的字符集;
Accept-Encoding:浏览器能够进行解码的数据编码方式,比如gzip。Servlet能够向支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这可以减少5到10倍的下载时间;
Accept-Language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到;
Authorization:授权信息,通常出现在对服务器发送的WWW-Authenticate头的应答中;
Connection:表示是否需要持久连接。如果Servlet看到这里的值为“Keep-Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一点,Servlet需要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入ByteArrayOutputStream,然后在正式写出内容之前计算它的大小;
Content-Length:表示请求消息正文的长度;
Cookie:这是最重要的请求头信息之一,常用来表示请求者的身份等;
From:请求发送者的email地址,由一些特殊的Web客户程序使用,浏览器不会用到它;
Host:初始URL中的主机和端口;
If-Modified-Since:只有当所请求的内容在指定的日期之后又经过修改才返回它,否则返回304“Not Modified”应答;
Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝;
Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。
User-Agent:浏览器类型,如果Servlet返回的内容与浏览器类型有关则该值非常有用;
UA-Pixels,UA-Color,UA-OS,UA-CPU:由某些版本的IE浏览器所发送的非标准的请求头,表示屏幕大小、颜色深度、操作系统和CPU类型。
2. 响应头:
Allow:服务器支持哪些请求方法(如GET、POST等);
Content-Encoding:文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader(“Accept-Encoding”))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面;
Content-Length:表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入ByteArrayOutputStram,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容;
Content-Type: 表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentTyep。 可在web.xml文件中配置扩展名和MIME类型的对应关系;
Date:当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦;
Expires:指明应该在什么时候认为文档已经过期,从而不再缓存它。
Last-Modified:文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置;
Location:表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302;
Refresh:表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setHeader(“Refresh”, “5; URL=http://host/path”)让浏览器读取指定的页面。注意这种功能通常是通过设置HTML页面HEAD区的实现,这是因为,自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。但是,对于Servlet来说,直接设置Refresh头更加方便。注意Refresh的意义是“N秒之后刷新本页面或访问指定页面”,而不是“每隔N秒刷新本页面或访问指定页面”。因此,连续刷新要求每次都发送一个Refresh头,而发送204状态代码则可以阻止浏览器继续刷新,不管是使用Refresh头还是<META HTTP-EQUIV=“Refresh” …>。注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它。