zoukankan      html  css  js  c++  java
  • http协议的总结

    HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统,其主要特点概括如下:

    1.支持客户/服务器模式。

    2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

    3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。

    4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

    5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

    HTTP请求报文解剖 

    HTTP请求报文由3部分组成(请求行+请求头+请求体): 


    下面是一个实际的请求报文:

     ①是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE。不过,当前的大多数浏览器只支持GET和POST,Spring 3.0提供了一个HiddenHttpMethodFilter,允许你通过“_method”的表单参数指定这些特殊的HTTP方法(实际上还是通过POST提交表单)。服务端配置了HiddenHttpMethodFilter后,Spring会根据_method参数指定的值模拟出相应的HTTP方法,这样,就可以使用这些HTTP方法对处理方法进行映射了。 

    ②为请求对应的URL地址,它和报文头的Host属性组成完整的请求URL,③是协议名称及版本号。 

    ④是HTTP的报文头,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。 

    ⑤是报文体,它将一个页面表单中的组件值通过param1=value1&param2=value2的键值对形式编码成一个格式化串,它承载多个请求参数的数据。不但报文体可以传递请求参数,请求URL也可以通过类似于“/chapter15/user.html? param1=value1&param2=value2”的方式传递请求参数。

     
    HTTP请求报文头属性 

    报文头属性是什么东西呢?我们不妨以一个小故事来说明吧。 

    引用
    快到中午了,张三丰不想去食堂吃饭,于是打电话叫外卖:老板,我要一份[鱼香肉丝],要12:30之前给我送过来哦,我在江湖湖公司研发部,叫张三丰。



    这里,你要[鱼香肉丝]相当于HTTP报文体,而“12:30之前送过来”,你叫“张三丰”等信息就相当于HTTP的报文头。它们是一些附属信息,帮忙你和饭店老板顺利完成这次交易。
    请求HTTP报文和响应HTTP报文都拥有若干个报文关属性,它们是为协助客户端及服务端交易的一些附属信息。 


    常见的HTTP请求报文头属性


    Accept
    请求报文可通过一个“Accept”报文头属性告诉服务端 客户端接受什么类型的响应。
    如下报文头相当于告诉服务端,俺客户端能够接受的响应类型仅为纯文本数据啊,你丫别发其它什么图片啊,视频啊过来,那样我会歇菜的~~~:

    Java代码  收藏代码
    1. Accept:text/plain  

    Accept属性的值可以为一个或多个MIME类型的值,关于MIME类型,大家请参考:http://en.wikipedia.org/wiki/MIME_type 

    Cookie
    客户端的Cookie就是通过这个报文头属性传给服务端的哦!如下所示: 

    Java代码  收藏代码
    1. Cookie: $Version=1; Skin=new;jsessionid=5F4771183629C9834F8382E23BE13C4C  


    服务端是怎么知道客户端的多个请求是隶属于一个Session呢?注意到后台的那个jsessionid=5F4771183629C9834F8382E23BE13C4C木有?原来就是通过HTTP请求报文头的Cookie属性的jsessionid的值关联起来的!(当然也可以通过重写URL的方式将会话ID附带在每个URL的后面哦)。 


    Referer
    表示这个请求是从哪个URL过来的,假如你通过google搜索出一个商家的广告页面,你对这个广告页面感兴趣,鼠标一点发送一个请求报文到商家的网站,这个请求报文的Referer报文头属性值就是http://www.google.com。 

    引用

    唐僧到了西天. 
    如来问:侬是不是从东土大唐来啊? 
    唐僧:厉害!你咋知道的! 
    如来:呵呵,我偷看了你的Referer...

    很多貌似神奇的网页监控软件(如著名的 我要啦),只要在你的网页上放上一段JavaScript,就可以帮你监控流量,全国访问客户的分布情况等报表和图表,其原理就是通过这个Referer及其它一些HTTP报文头工作的。 

    Cache-Control
    对缓存进行控制,如一个请求希望响应返回的内容在客户端要被缓存一年,或不希望被缓存就可以通过这个报文头达到目的。 

    如以下设置,相当于让服务端将对应请求返回的响应内容不要在客户端缓存: 

    Java代码  收藏代码
    1. Cache-Control: no-cache  


    其它请求报文头属性
    参见:http://en.wikipedia.org/wiki/List_of_HTTP_header_fields 

    HTTP响应报文解剖 

    响应报文结构
    HTTP的响应报文也由三部分组成(响应行+响应头+响应体): 


    以下是一个实际的HTTP响应报文: 

     

    ①报文协议及版本; 
    ②状态码及状态描述; 
    ③响应报文头,也是由多个属性组成; 
    ④响应报文体,即我们真正要的“干货”。 

    响应状态码 

    和请求报文相比,响应报文多了一个“响应状态码”,它以“清晰明确”的语言告诉客户端本次请求的处理结果。
    HTTP的响应状态码由5段组成:

    • 1xx 消息,一般是告诉客户端,请求已经收到了,正在处理,别急...
    • 2xx 处理成功,一般表示:请求收悉、我明白你要的、请求已受理、已经处理完成等信息.
    • 3xx 重定向到其它地方。它让客户端再发起一个请求以完成整个处理。
    • 4xx 处理发生错误,责任在客户端,如客户端的请求一个不存在的资源,客户端未被授权,禁止访问等。
    • 5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错,HTTP版本不支持等。



    以下是几个常见的状态码:
    200 OK
    你最希望看到的,即处理成功! 

    303 See Other
    我把你redirect到其它的页面,目标的URL通过响应报文头的Location告诉你。 

    引用
    悟空:师傅给个桃吧,走了一天了 
    唐僧:我哪有桃啊!去王母娘娘那找吧


    304 Not Modified
    告诉客户端,你请求的这个资源至你上次取得后,并没有更改,你直接用你本地的缓存吧,我很忙哦,你能不能少来烦我啊! 

    404 Not Found
    你最不希望看到的,即找不到页面。如你在google上找到一个页面,点击这个链接返回404,表示这个页面已经被网站删除了,google那边的记录只是美好的回忆。 

    500 Internal Server Error
    看到这个错误,你就应该查查服务端的日志了,肯定抛出了一堆异常,别睡了,起来改BUG去吧!
    其它的状态码参见:http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
    有些响应码,Web应用服务器会自动给生成。你可以通过HttpServletResponse的API设置状态码:

    Java代码  收藏代码
    1. //设置状态码,状态码在HttpServletResponse中通过一系列的常量预定义了,如SC_ACCEPTED,SC_OK  
    2. void    setStatus(int sc)   



    常见的HTTP响应报文头属性
    Cache-Control
    响应输出到客户端后,服务端通过该报文头属告诉客户端如何控制响应内容的缓存。
    下面,的设置让客户端对响应内容缓存3600秒,也即在3600秒内,如果客户再次访问该资源,直接从客户端的缓存中返回内容给客户,不要再从服务端获取(当然,这个功能是靠客户端实现的,服务端只是通过这个属性提示客户端“应该这么做”,做不做,还是决定于客户端,如果是自己宣称支持HTTP的客户端,则就应该这样实现)

    Java代码  收藏代码
    1. Cache-Control: max-age=3600  

    ETag
    一个代表响应服务端资源(如页面)版本的报文头属性,如果某个服务端资源发生变化了,这个ETag就会相应发生变化。它是Cache-Control的有益补充,可以让客户端“更智能”地处理什么时候要从服务端取资源,什么时候可以直接从缓存中返回响应。
    关于ETag的说明,你可以参见:http://en.wikipedia.org/wiki/HTTP_ETag。 
    Spring 3.0还专门为此提供了一个org.springframework.web.filter.ShallowEtagHeaderFilter(实现原理很简单,对JSP输出的内容MD5,这样内容有变化ETag就相应变化了),用于生成响应的ETag,因为这东东确实可以帮助减少请求和响应的交互。
    下面是一个ETag: 
    Java代码  收藏代码
    1. ETag: "737060cd8c284d8af7ad3082f209582d"  

    Location
    我们在JSP中让页面Redirect到一个某个A页面中,其实是让客户端再发一个请求到A页面,这个需要Redirect到的A页面的URL,其实就是通过响应报文头的Location属性告知客户端的,如下的报文头属性,将使客户端redirect到iteye的首页中:
    Java代码  收藏代码
    1. Location: http://www.iteye.com  

    Set-Cookie
    服务端可以设置客户端的Cookie,其原理就是通过这个响应报文头属性实现的:
    Java代码  收藏代码
    1. Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1  
     
    其它HTTP响应报文头属性
    更多其它的HTTP响应头报文,参见:http://en.wikipedia.org/wiki/List_of_HTTP_header_fields 


    如何写HTTP请求报文头
    在服务端可以通过HttpServletResponse的API写响应报文头的属性: 

    Java代码  收藏代码
    1. //添加一个响应报文头属性  
    2. void    setHeader(String name, String value)   
    象Cookie,Location这些响应都是有福之人,HttpServletResponse为它们都提供了VIP版的API: 
    Java代码  收藏代码
    1. //添加Cookie报文头属性  
    2. void addCookie(Cookie cookie)   
    3.   
    4. //不但会设置Location的响应报文头,还会生成303的状态码呢,两者天仙配呢  
    5. void    sendRedirect(String location)  

    客户端发送请求的安全问题:
    为了防止人为恶意抓取请求信息攻击服务器,这边一般都会通过MD5或者Aes在请求头注入参数加密,
    一般都是注入 时间戳+特定的字符串去加密,然后服务端进行校验。
    如下面一段实际项目中OC的加密请求头代码:

    开发常用Post与Get请求的区别:

    一般我们从服务器取数据用get,向服务器提交数据用post。

    GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。

    GET和POST还有一个重大区别,简单的说:

    GET产生一个TCP数据包;

    POST产生两个TCP数据包。

    长的说:

    对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

    而对于POST,浏览器先发送header,服务器响应100 才会继续,浏览器再发送data,服务器响应200 ok(返回数据)。

    其他参考学习链接: https://www.cnblogs.com/wxisme/p/6212797.html

  • 相关阅读:
    ASP.NET Web API 2 框架揭秘
    跨境之二 对外服务接口接收订单数据(跨境通关申报系统)
    关于程序员的59条搞笑但却真实无比的编程语录
    linux终端常用快捷键
    [ json editor] 如何在网页中使用Json editor 插件
    【简洁之美】裴波那切数列生成器 python
    python 实现树结构的打印
    windows python文件拷贝到linux上执行问题
    python 中变量的命名方法
    <select> 标签使用
  • 原文地址:https://www.cnblogs.com/xiafancai/p/10451325.html
Copyright © 2011-2022 走看看