网络原理 - 12(HTTP/HTTPS - 3 - 响应)
目录
认识“状态码”(status code)
200 OK
404 Not Found
403 Forbidden
405 Method Not Allowed
500 Internal Server Error
504 Gateway Timeout
302 Move temporarily
301 Moved Permanently
418 I am a teaport
状态码小结:
认识响应“报头”(header)
Content - Type
构造 HTTP 请求
通过第三方工具进行构造
通过代码来构造 HTTP 请求
完!
认识“状态码”(status code)
状态码是表示一个页面的结果。(是访问成功,还是失败,话是其他的一些情况...)
HTTP 中的状态码都是约定好的:
上面的状态码并不需要全部都记住,只需要直到几个常见的状态码即可~~
200 OK
这是一个最常见的状态码, 表示访问成功
404 Not Found
表示没有找到资源。
浏览器输入一个 URL,目的就是为了访问对方服务器上的一个资源。如果这个 URL 标识的资源不存在,那么就会出现 404。例如,在浏览器中输入 www.bilibli.com/index.html,此时就在尝试访问 哔哩哔哩上的 /index.html 这个资源。
如果输入正确,就可以正确访问到,但是如果输入错误,比如 www.bilibili.com/index333.html,就会看到 404 这样的响应。(不过 bilibili 比较有特点,他特意为 404 做了一个比较符合宅男动漫的页面~~)
403 Forbidden
表示访问被拒绝。有的页面通常需要用户具有一定的权限(比如登陆后才能进行访问)如果用户没有登录直接访问,就容易看到 403。
例如:我们在码云上查看一个其他人的私人仓库,就会出现 403,参考链接:https://gitee.com/HGtz2222/blog_python
405 Method Not Allowed
前面我们学习了 HTTP 中所支持的方法,有 GET,POST,PUT,DELETE 等等。
但是对方的服务器不一定支持所有的方法,比如:服务器只支持 GET 请求,但是我们发送了一个 POST,就会出现 405 Method Not Allowed。
500 Internal Server Error
服务器内部出现错误,一般是服务器的代码执行过程中,遇到了一些特殊的情况(服务器崩溃)会产生这个状态码~~
504 Gateway Timeout
当服务器负载比较大的时候,服务器处理单条请求的时间消耗的时间就会很长,就可能出现访问服务器超时。这种情况可能是服务器挂了,也可能是网络挂了~~
302 Move temporarily
临时重定向
理解“重定向”
就相当于手机号码中的“呼叫转移”功能。
比如我们本来的手机号是 123-4567-7899,后来换了一个新的号码是 999-4567-7891,此时难道是一个一个朋友告诉我们的新号码码??
我们可以去办理一个呼叫转移业务,其他人拨打 123-4567-7899 的时候,就会自动转移到999-4567-7891 上
我们在登录页面经常会见到 302,用户实现登陆成功后自动跳转到主页。
响应报文中的 header 部分会包含一个 Location 字段,表示要跳转到那个页面~~
我们以码云的登录为例:登陆后的抓包结果:
可以看到 header 中的 Location:https://gitee.com/,接下来浏览器就会自动发送 GET
请求,获取 https://gitee.com/
301 Moved Permanently
永久重定向,当浏览器收到这种响应时候,后续的请求都会被自动改成新的地址,不必多一次跳转了。(可以影响到浏览器的缓存)
在上面 301 和 302 这种重定向报文的响应中,会有一个特殊的 header 叫做 Location,描述了要重定向的位置是在哪里~~
418 I am a teaport
一个特殊的状态码,没有实际的含义,I am a teaport 我是个茶壶(我是个杯具~~)
设计 HTTP 协议的大佬开玩笑 == 》 “彩蛋~”
状态码小结:
认识响应“报头”(header)
响应报头的基本格式和请求报头的格式基本一致
类似 Content - Type,Content - Length 等属性的含义也和请求中的含义一致~~
Content - Type
响应中的 Content - Type 常见取值有以下几种:
text/html :body 数据格式是 HTML
text/css: body 数据格式是 CSS
application/javascript: body 数据格式是 Javascript
application/json: body 数据格式是 JSON
构造 HTTP 请求
通过第三方工具进行构造
使用 postman 就可以构造 HTTP 请求~
每个标签页,就是一个构造 HTTP 请求的配置页面了,点击 Send 发送按钮,就能发送请求到目标服务器了~~
还有一个很牛逼的点是:postman 是一个有对象的软件 == > postwoman~~
通过代码来构造 HTTP 请求
任何一种编程语言,只要能够操作网络,都可以构造 HTTP 请求!!
所谓”发送 HTTP 请求“,本质上就是按照 HTTP 的格式往 TCP Socket 中写入一个字符串。
所谓”接受 HTTP 响应“,本质上就是从 TCP Socket 中读取一个字符串,再按照 HTTP 的格式来解析。
我们就可以基于 Socket 的知识,构造出一个简单的 HTTP 客户端程序,用来发送各种类型的 HTTP 请求。
public class HttpClient {private Socket socket;private String ip;private int port;public HttpClient(String ip, int port) throws IOException {this.ip = ip;this.port = port;socket = new Socket(ip, port);}public String get(String url) throws IOException {StringBuilder request = new StringBuilder();// 构造首行request.append("GET " + url + " HTTP/1.1\n");// 构造 headerrequest.append("Host: " + ip + ":" + port + "\n");// 构造空行request.append("\n");// 发送数据OutputStream outputStream = socket.getOutputStream();outputStream.write(request.toString().getBytes());// 读取响应数据InputStream inputStream = socket.getInputStream();byte[] buffer = new byte[1024 * 1024];int n = inputStream.read(buffer);return new String(buffer, 0, n, "utf-8");}public String post(String url, String body) throws IOException {StringBuilder request = new StringBuilder();// 构造首行request.append("POST " + url + " HTTP/1.1\n");// 构造 headerrequest.append("Host: " + ip + ":" + port + "\n");request.append("Content-Length: " + body.getBytes().length + "\n");request.append("Content-Type: text/plain\n");// 构造空行request.append("\n");// 构造 bodyrequest.append(body);// 发送数据OutputStream outputStream = socket.getOutputStream();outputStream.write(request.toString().getBytes());// 读取响应数据InputStream inputStream = socket.getInputStream();byte[] buffer = new byte[1024 * 1024];int n = inputStream.read(buffer);return new String(buffer, 0, n, "utf-8");}public static void main(String[] args) throws IOException {HttpClient httpClient = new HttpClient("www.bilibili.com",80);String resp = httpClient.get("/index.html");System.out.println(resp);String postResp = httpClient.post("/index.html","this is a body");System.out.println(postResp);}
}