HTTP请求:
一、请求行:
请求行由请求格式:
方法字段、URL字段和HTTP协议版
本字段3个字段组成,它们用空格分隔。
例如:GET /index.html HTTP/1.1。
请求格式 | 方法字段 URL字段 HTTP协议版 |
例如 | GET /index.html HTTP/1.1 |
二、请求头:
字段 | 含义 |
---|---|
Accept | 告诉服务器,客户端支持的数据类型 |
Accept-Charset | 告诉服务器,客户端采用的编码。 |
Accept-Encoding | 告诉服务器,客户机支持的数据压缩格式。 |
Accept-Language | 告诉服务器,客户机的语言环境 |
Host | 客户机通过这个头告诉服务器,想访问的主机名。 |
If-Modified-Since: | 客户机通过这个头告诉服务器,资源的缓存时间。(好多请求中不显示) |
Referer | 客户机通过这个头告诉服务器,它是从哪个资源来访问服务器的。(一般用于防盗链) |
User-Agent: | 客户机通过这个头告诉服务器,客户机的软件环境 |
Cookie | 客户机通过这个头告诉服务器,可以向服务器带数据 |
Connection | 客户机通过这个头告诉服务器,请求完后是关闭还是保持链接 |
Date | 客户机通过这个头告诉服务器,客户机当前请求时间。 |
三、响应头:
字段 | 含义 |
---|---|
Location | 这个头配合302状态码使用,告诉用户端找谁。 |
Server | 服务器通过这个头,告诉浏览器服务器的类型 |
Content-Encoding | 服务器通过这个头,告诉浏览器数据采用的压缩格式。 |
Content-Length | 服务器通过这个头,告诉浏览器回送数据的长度。 |
Content-Language | 服务器通过这个头,告诉服务器的语言环境。 |
Content-Type | 服务器通过这个头,回送数据的类型 |
Last-Modified | 服务器通过这个头,告诉浏览器当前资源的缓存时间。 |
Refresh | 服务器通过这个头,告诉浏览器隔多长时间刷新一次。 |
Content-Disposition | 服务器通过这个头,告诉浏览器以下载的方式打开数据。 |
Transfer-Encoding | 服务器通过这个头,告诉浏览器数据的传送格式。 |
ETag | 与缓存相关的头。 |
Expires | 服务器通过这个头,告诉浏览器把回送的数据缓存多长时间。-1或0不缓存。 |
Cache-Control和Pragma | 服务器通过这个头,也可以控制浏览器不缓存数据。 |
Connection | 服务器通过这个头,响应完是保持链接还是关闭链接 |
Date | 告诉客户机,返回响应的时间。 |
四、请求正文:
1、请求头和请求正文之间有一空格(很重要),代表请求头的结束。
2、不一定什么时候有:
1)、在http请求中,如果是GET请求:
那么请求的数据会在请求的路径后面
GET /index.html?username=tom&password=123
2)、在http请求中,如果是POST请求:
那么请求的数据会
在请求的正文中
五、扩展:
1、请求方式:
根据HTTP标准,HTTP请求可以使用多种请求方法:
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
get请求参数在 请求行中
请求参数在请求体中
2、If-Modified-Since和Last-Modified:
1、Last-Modified 与If-Modified-Since都是用来记录页面的最后修改时间。
当客户端访问页面时,服务器会将页面最后修改时间通过 Last-Modified 标识由服务器发往客户端,客户端记录修改时间。
2、 再次请求本地存在的cache页面时,客户端会通过 If-Modified-Since 头将先前服务器端发过来的最后修改时间戳发送回去,服务器端通过这个时间戳判断客户端的页面是否是最新的。
3、如果不是最新的,则返回新的内容,如果是最新的,则 返回 304 告诉客户端其本地 cache 的页面是最新的。
4、于是客户端就可以直接从本地加载页面了,这样在网络上传输的数据就会大大减少,同时也减轻了服务器的负担
3、响应状态码:
分类 | 分类描述 |
---|---|
1** | (正确响应)信息,服务器收到请求,需要请求者继续执行操作(服务器什么都没有做) |
2** | 成功,操作被成功接收并处理 |
3** | (正确响应)重定向,需要进一步的操作以完成请求 (服务器做了一部分, 后续还要做) |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
更加详细的可以参考菜鸟教程
常见的响应状态码:
200 OK:
你最希望看到的,即处理成功!
301 redirect:
301 代表永久性转移(Permanently Moved)
302 redirect:
302 代表暂时性转移(Temporarily Moved )
303 See Other:
我把你redirect到其它的页面,目标的URL通过响应报文头的Location告诉你。
304 Not Modified:
告诉客户端,你请求的这个资源至你上次取得后,并没有更改,你直接用你本地的缓存吧,我很忙哦,你能不能少来烦我啊!(走缓存)
404 Not Found:
你最不希望看到的,即找不到页面。如你在google上找到一个页面,点击这个链接返回404,表示这个页面已经被网站删除了,google那边的记录只是美好的回忆。
500 Internal Server Error:
看到这个错误,你就应该查查服务端的日志了,肯定抛出了一堆异常,别睡了,起来改BUG去吧!
4、GET和POST的区别:
1、 在客户端,Get方式在通过URL提交数据,数据在URL中可以看到;
POST方式,数据放在HTTP包的body中。
2、 GET方式提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST则没
有此限制。
3、安全性问题。正如在(1)中提到,使用 Get 的时候,参数会显示在地址栏上,而
Post 不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 get;如果用户
输入的数据不是中文字符而且包含敏感数据,那么还是使用 post为好。
4.、服务器取值方式不一样。GET方式取值,如php可以使用$_GET来取得变量的值,而
POST方式通过$_POST来获取变量的值。
302 + location和Referer:
1、重定向:302 + location------->response
定义两个Servlet分别为:ServeltFrist.java和ServeltSecond.java
public class ServeltFrist extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置状态码为302
response.setStatus(302);
//设置响应头的location值为:http://lcoalhost/day03_4/second
response.setHeader("location", "http://localhost/day03_4/second");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
//--------------------------------------------------------------------------------------------
public class ServeltSecond extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("我是重定向得到的");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
2、Referer(防盗链)
一个index.html页面有一个超链接。链接到Servlet的RefererTest.java:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
双十一抢购苹果手机:<br>
<a href="/day03_4/referer">点击进行iphone X抢购</a>
</body>
</html>
//------------------------------------------------------------------------------------------------(仅用于分开)
public class RefererTest extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String referer = request.getHeader("Referer");
if ("http://localhost/day03_4/index.html".equals(referer)) {
response.getWriter().write("恭喜你抢购成功");
} else {
response.getWriter().write("你正在进行非法访问");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
下面附上没人用的破防盗链(仅用于自己有个印象)
public class PoReferer {
public static void main(String[] args) throws IOException {
// 得到抢购链接
URL url = new URL("http://localhost/day03_4/referer");
// 表示得到远程连接的对象
URLConnection conn = url.openConnection();
conn.addRequestProperty("Referer", "http://localhost/day03_4/index.html");
conn.connect();
// 得到远程了解资源的流对象
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
// 打印流对象
String line = br.readLine();
System.out.println(line);
}
}
注意:
1、POST请求有请求体,故与GET请求相比,请求头中多了Content-Length和Content-Type属性。
2、在响应中:响应行和响应行都是有浏览器内部解析的;而只有响应体才是展示在我们所看到的(页面源码);响应正文内容由浏览器进行解析显示在页面上