HTTP协议(Requset、Response)

http协议

对浏览器客户端 和 服务器端 之间数据传输的格式规范

查看http协议的方法:

  1. 使用火狐的firebug插件(右键->firebug->网络)
  2. 使用谷歌的“审查元素”
  3. 使用系统自带的telnet工具(远程访问工具) 
    a)telnet localhost 8080 访问tomcat服务器
    b)ctrl+] 回车 可以看到回显
    c)输入请求内容

    d)回车,即可查看到服务器响应信息

http协议内容:

例:访问本地服务器


requset请求 数据格式

Http请求(浏览器->服务器)

GET /WebRoot/hello HTTP/1.1 -- 请求行

Host: localhost:8080 -- 请求头(多个key-value对象)

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Connection: keep-alive

-- 一个空行

name=123&password=123456 --(可选)请求正文/实体内容

------------------------------------请求行----------------------------------------------------------

GET   /WebRoot/hello   HTTP/1.1 

开始访问资源请求一次,之后文件中每有一个地址都会请求一次

#http协议版本

http1.0:当前浏览器客户端与服务器端建立连接之后,只能发送一次请求,一次请求之后连接关闭。

http1.1:当前浏览器客户端与服务器端建立连接之后,可以在一次连接中发送多次请求。(基本都使用1.1)

#请求资源

URL: 统一资源定位符。http://localhost:8080/WebRoot/hello。只能定位互联网资源。是URI 的子集。URL=协议+主机端口+URI

URI: 统一资源标记符。/WebRoot/hello。用于标记任何资源。可以是本地文件系统、局域网的资源、 可以是互联网资源。

#请求方式

常见的请求方式: GET 、 POST、 HEAD、 TRACE、 PUT、 CONNECT 、DELETE

常用的请求方式: GET 和 POST

例:表单提交

<form action="提交地址" method="GET/POST">

<form>

GET方式提交 

  1. 参数数据跟在地址栏(URI)后。以?开头、多个参数之间以&分割:GET  /WebRoot/testMethod.html?name=123&password=123456  HTTP/1.1
  2. GET提交参数数据有限制,不超过1KB。(实际上URL不存在参数上限的问题,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制,IE对URL长度的限制是2083字节)
  3. GET方式不适合提交敏感密码。
  4. 注意: 浏览器直接访问的请求,默认提交方式是GET方式。火狐浏览器以Get方式提交带参数的数据,会重复提交两次

POST方式提交

  1. 参数跟在请求的实体内容中。没有?开头、多个参数之间以&分割
  2. POST提交的参数数据没有限制。
  3. POST方式提交敏感数据。

-------------------------------------请求头----------------------------------------------------------

键值对,例:常见的请求头

Accept: text/html,image/* -- 浏览器接受的数据类型

Accept-Charset: ISO-8859-1 -- 浏览器接受的编码格式

Accept-Encoding: gzip,compress --浏览器接受的数据压缩格式

Accept-Language: en-us,zh- --浏览器接受的语言

Host: www.it315.org:80 --(必须的)当前请求访问的目标地址(主机:端口)

If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT --浏览器最后的缓存时间

Referer: http://www.it315.org/index.jsp -- 当前请求来自于哪里(可用来判断非法链接)

User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0) --浏览器类型

Cookie:name=123 -- 浏览器保存的cookie信息

Connection: close/Keep-Alive -- 浏览器跟服务器连接状态。close:连接关闭 keep-alive:保持连接

Date: Tue, 11 Jul 2000 18:23:51 GMT -- 请求发出的时间
------------------------------------请求正文/实体内容----------------------------------------------

请求头和请求正文之间是一个空行,它表示请求头已经结束,接下来的是请求正文。

只有POST提交的参数会放到实体内容中

=====================请求对象================================

HttpServletRequest对象:

tomcat服务器把请求信息封装到HttpServletRequest对象,把响应信息封装到HttpServletResponse对象。然后调用servlet的方法,传入request和response对象

HttpServletRequest对象用于获取请求数据,核心的API:

请求行: 

request.getMethod();          获取请求方式

request.getRequetURI(); /  request.getRequetURL();            获取请求资源

request.getProtocol();           获取请求http协议版本

request.getQueryString();           (获取GET方式传递的参数)

请求头

request.getHeaderNames();            获取所有的请求头名称

request.getHeader("名称");            根据请求头获取请求值

实体内容

request.getInputStream();            获取实体内容数据(获取POST方式传递的参数)

GET、POST请求参数 统一通用方便的获取方法

request.getParameterNames();          获取所有参数名称列表(参数名为 html表单中数据标签的name属性值)

request.getParameter("参数名");         根据参数名获取参数值(只能获取一个值的参数)

request.getParameterValue("参数名“);         根据参数名获取参数值(可以获取多个值的参数)

编码问题

修改GET方式参数编码:

手动解码:String name = new String(request.getParameter("参数名").getBytes("iso-8859-1"),"utf-8");

修改POST方式参数编码:

设置参数查询码表:request.setCharacterEncoding("utf-8");         放在查询参数之前,只对实体内容起作用

改服务器配置文件:找到并在%tomcat%/conf/server.xml文件Connector标签中加入  URIEncoding="utf-8"

请求案例:获取浏览器的类型(user-agent), 防止非法链接(referer)
 


response响应 数据格式

 

Http响应(服务器->浏览器)

HTTP/1.1 200 OK --响应行

Server: Apache-Coyote/1.1 --响应头(key-vaule)

Content-Length: 24

Date: Fri, 30 Jan 2015 01:54:57 GMT

--一个空行

this is hello servlet!!! --响应正文/实体内容

-------------------------------------响应行----------------------------------------------------------

HTTP/1.1  200  OK

#状态码: 服务器处理请求的结果(状态)

常见的状态:
200: 表示请求处理完成并完美返回
302: 表示请求需要进一步细化。
404: 表示客户访问的资源找不到。
500: 表示服务器的资源发送错误。(服务器内部错误)

#状态描述

--------------------------------------响应头----------------------------------------------------------

键值对,例:常见的响应头

Location: 重定向地址 #-#-#表示重定向的地址,该头和302的状态码一起使用。=====

Server:apache tomcat --表示服务器的类型

Content-Encoding: gzip --表示服务器发送给浏览器的数据压缩类型

Content-Length: 80 --表示服务器发送给浏览器的实体正文长度

Content-Language: zh-cn --表示服务器支持的语言

Content-Type: text/html; charset=GB2312 #-#-#表示服务器发送给浏览器的 数据类型 及 内容编码=====

Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT --表示服务器资源的最后修改时间

Refresh: 秒数;url=地址 #-#-#表示定时刷新到指定页面=====

Content-Disposition: attachment; filename=aaa.zip --表示告诉浏览器以下载方式打开资源(下载文件时用到)

Transfer-Encoding: chunked

Set-Cookie:SS=Q0=5Lb_nQ; path=/search --表示服务器发送给浏览器的cookie信息(会话管理用到)

Expires: -1 --表示通知浏览器不进行缓存

Cache-Control: no-cache --同上

Pragma: no-cache --同上

Connection: close/Keep-Alive --表示服务器和浏览器的连接状态。close:关闭连接 keep-alive:保存连接

------------------------------------响应正文/实体内容----------------------------------------------

响应正文就是服务器返回给浏览器的资源的内容:

由响应头的Content-···等属性告知浏览器 响应正文的长度、编码、媒体类型等(MIME Type是经过 ietf 组织协商,以 RFC 的形式作为建议标准发布在网上的)

由response对象PrintWriter写入数据内容

======================响应对象==============================

HttpServletResponse对象:

tomcat服务器把请求信息封装到HttpServletRequest对象,把响应信息封装到HttpServletResponse对象。然后调用servlet的方法,传入request和response对象
HttpServletResponse对象用于修改响应信息,核心的API:

响应行: 

response.setStatus();           设置状态码

响应头: 

response.setHeader("name","value");           设置响应头

response.sendRedirect(url);         重定向

response.setContentType("text/html;charset=utf-8");         发送给浏览器的数据类型 及内容编码

实体内容:(浏览器直接能够看到)

response.getWriter().writer();          发送字符实体内容

response.getOutputStream().writer()          发送字节实体内容

tomcat服务器把response对象的内容转换成响应格式内容,再发送给浏览器解析。

编码问题

response.setCharacterEncoding("utf-8");         放在响应实体内容代码之前,对getOutputStream().writer()字节流不起作用

响应案例:请求重定向(Location),定时刷新(refresh),content-Type数据类型(在tomcat服务器web.xml中用mime-type标签规定了数据类型,例如:text/html发送HTML文本;image/jpg发送图片)

               //=================================HTTP RESPONS=============================

  

一个域是由schema、host、port三者共同组成,与路径无关。所谓跨域,是指在http://example-foo.com/域上通过XMLHttpRequest对象调用http://example-bar.com/域上的资源。CORS约定服务器端和浏览器在HTTP协议之上,通过一些额外HTTP头部信息,进行跨域资源共享的协商。服务器端和浏览器都必需遵循规范中的要求。

CORS把HTTP请求分成两类,不同类别按不同的策略进行跨域资源共享协商。

1. 简单跨域请求。
当HTTP请求出现以下两种情况时,浏览器认为是简单跨域请求:

1). 请求方法是GET、HEAD或者POST,并且当请求方法是POST时,Content-Type必须是application/x-www-form-urlencoded, multipart/form-data或着text/plain中的一个值。
2). 请求中没有自定义HTTP头部。

对于简单跨域请求,浏览器要做的就是在HTTP请求中添加Origin Header,将JavaScript脚本所在域填充进去,向其他域的服务器请求资源。服务器端收到一个简单跨域请求后,根据资源权限配置,在响应头中添加Access-Control-Allow-Origin Header。浏览器收到响应后,查看Access-Control-Allow-Origin Header,如果当前域已经得到授权,则将结果返回给JavaScript。否则浏览器忽略此次响应。

2. 带预检(Preflighted)的跨域请求。
当HTTP请求出现以下两种情况时,浏览器认为是带预检(Preflighted)的跨域请求:

1). 除GET、HEAD和POST(only with application/x-www-form-urlencoded, multipart/form-data, text/plain Content-Type)以外的其他HTTP方法。
2). 请求中出现自定义HTTP头部。

带预检(Preflighted)的跨域请求需要浏览器在发送真实HTTP请求之前先发送一个OPTIONS的预检请求,检测服务器端是否支持真实请求进行跨域资源访问,真实请求的信息在OPTIONS请求中通过Access-Control-Request-Method Header和Access-Control-Request-Headers Header描述,此外与简单跨域请求一样,浏览器也会添加Origin Header。服务器端接到预检请求后,根据资源权限配置,在响应头中放入Access-Control-Allow-Origin Header、Access-Control-Allow-Methods和Access-Control-Allow-Headers Header,分别表示允许跨域资源请求的域、请求方法和请求头。此外,服务器端还可以加入Access-Control-Max-Age Header,允许浏览器在指定时间内,无需再发送预检请求进行协商,直接用本次协商结果即可。浏览器根据OPTIONS请求返回的结果来决定是否继续发送真实的请求进行跨域资源访问。这个过程对真实请求的调用者来说是透明的。

XMLHttpRequest支持通过withCredentials属性实现在跨域请求携带身份信息(Credential,例如Cookie或者HTTP认证信息)。浏览器将携带Cookie Header的请求发送到服务器端后,如果服务器没有响应Access-Control-Allow-Credentials Header,那么浏览器会忽略掉这次响应。

这里讨论的HTTP请求是指由Ajax XMLHttpRequest对象发起的,所有的CORS HTTP请求头都可由浏览器填充,无需在XMLHttpRequest对象中设置。以下是CORS协议规定的HTTP头,用来进行浏览器发起跨域资源请求时进行协商:
1. Origin。HTTP请求头,任何涉及CORS的请求都必需携带。
2. Access-Control-Request-Method。HTTP请求头,在带预检(Preflighted)的跨域请求中用来表示真实请求的方法。
3. Access-Control-Request-Headers。HTTP请求头,在带预检(Preflighted)的跨域请求中用来表示真实请求的自定义Header列表。
4. Access-Control-Allow-Origin。HTTP响应头,指定服务器端允许进行跨域资源访问的来源域。可以用通配符*表示允许任何域的JavaScript访问资源,但是在响应一个携带身份信息(Credential)的HTTP请求时,Access-Control-Allow-Origin必需指定具体的域,不能用通配符。
5. Access-Control-Allow-Methods。HTTP响应头,指定服务器允许进行跨域资源访问的请求方法列表,一般用在响应预检请求上。
6. Access-Control-Allow-Headers。HTTP响应头,指定服务器允许进行跨域资源访问的请求头列表,一般用在响应预检请求上。
7. Access-Control-Max-Age。HTTP响应头,用在响应预检请求上,表示本次预检响应的有效时间。在此时间内,浏览器都可以根据此次协商结果决定是否有必要直接发送真实请求,而无需再次发送预检请求。

8. Access-Control-Allow-Credentials。HTTP响应头,凡是浏览器请求中携带了身份信息,而响应头中没有返回Access-Control-Allow-Credentials: true的,浏览器都会忽略此次响应。

总结:只要是带自定义header的跨域请求,在发送真实请求前都会先发送OPTIONS请求,浏览器根据OPTIONS请求返回的结果来决定是否继续发送真实的请求进行跨域资源访问。所以复杂请求肯定会两次请求服务端。

js 端的ajax请求:

$.ajax({

url: "http://test.com",

dataType: 'json',

type: 'GET',

beforeSend: function (xhr) {

xhr.setRequestHeader("Test", "testheadervalue");

},

async: false,

cache: false,

//contentType: 'application/x-www-form-urlencoded',

success: function (sResponse) {

}

});

服务端的action

//允许跨域访问

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT");

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Test");

HTTP请求方法

根据HTTP标准,HTTP请求可以使用多种请求方法。
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

1 GET     请求指定的页面信息,并返回实体主体。
2 HEAD     类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
3 POST     向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
4 PUT     从客户端向服务器传送的数据取代指定的文档的内容。
5 DELETE      请求服务器删除指定的页面。
6 CONNECT     HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
7 OPTIONS     允许客户端查看服务器的性能。
8 TRACE     回显服务器收到的请求,主要用于测试或诊断。

猜你喜欢

转载自blog.csdn.net/qq_36826506/article/details/82143913
今日推荐