「HTTP协议其实很简单.02」理解HTTP协议的第一行

「HTTP协议其实很简单.02」理解HTTP协议的第一行

本篇主题:理解HTTP协议的第一行

上一篇,讲了讲怎么去理解协议,其中的核心点就是用计算机的思维模式去思考。这一篇开始正式接触HTTP协议的第一行。


古语讲:预先善其事,必先利其器。所以在开始之前,我们需要了解一个“工具”(一个软件的操作)。这个工具就是去看HTTP协议内容的工具,有的小伙伴可能已经想到了,是F12。下面讲讲工具的打开方法:

  1. 打开浏览器(chrome、360、qq随便什么都可以)
  2. 按下快捷键F12。你应该会看到下图:

「HTTP协议其实很简单.02」理解HTTP协议的第一行

3.下面的每一条代表的是一次HTTP请求。点击可以查看这一次请求的具体内容。

工具准备好了,下面进入正题。


我们设想一个打电话的场景,目标是找某讯公司/研发部/XX工作室/开发小组,而我们只知道某讯公司前台的电话(0755-00000000)。

拨通电话,问候之后,我们要告诉对方,我找研发部xx工作室开发小组,顺利的情况下前台小姐姐会把电话转给xx工作室开发小组。

我们梳理一下整个过程中的重要信息:0755-00000000/研发部/农药工作室/开发小组

是不是有点像:pvp.pp.com/web201605/herodetail/116.shtml

电话号码就像一个网址的域名(pvp.pp.com),研发部/农药工作室 就像web201605/herodetail,开发小组就像116.shtml

这些信息帮助前台小姐姐很精准的找到我们想找的人,是这次电话场景中必不可少的内容。

同样这也是HTTP协议中最重要的组成部分,我们来看看他们在HTTP协议中是如何体现的。

我们以这个网址为例来看: https://sale.vmall.com/pseries.html?cid=10618

注意打开浏览器后先按下F12,然后再输入网址,会在开发人员工具里看到这样的界面:

「HTTP协议其实很简单.02」理解HTTP协议的第一行

(注意,有很多网址看不到view source,找不到就换个别的网址)

依次点击图中红框的位置,会看到下图:

「HTTP协议其实很简单.02」理解HTTP协议的第一行

这就是http协议的第一行,这一行内容告诉服务器我需要什么。就像打电话告诉前台小姐姐我要找谁一样。

我们可以写一个程序代替浏览器发起这一次请求。来完整的看一看一个完整的HTTP协议请求和响应的内容分别是什么。

这次实验的地址是: www.12371yun.com/news-info.php?cid=2&id=69

下面是模拟浏览器的代码:

import java.io.*;import java.net.InetsocketAddress;import java.net.Socket;import java.net.SocketAddress;public class MyChrome { public static void main(String[] args) throws IOException { String host = \”www.12371yun.com\”; //定义要访问哪个服务器,就像是要拨打哪个电话 int port = 80; //定义端口,一般HTTP请求的默认商品是80 SocketAddress endpoint = new InetSocketAddress(host, port); //创建地址对象 // 与服务端建立连接 Socket socket = new Socket(); //Socket类是TCP/IP请求的核心类。要知道HTTP是建立的TCP/IP基础上的。 socket.connect(endpoint,2000); //开始连接服务器,就好比开始拨打电话,参数2000是超时时间,意思是2秒中没有影响则停止。 // 建立连接后获得输出流 OutputStream os = socket.getOutputStream(); //获得输出流,用来向服务器发送报文。告诉服务器我想干什么 //message字符串就是具体的请求报文 String message = \”GET /news-info.php?cid=2&id=69 HTTP/1.1n\” //第一行告诉服务器我的请求方式是GET,需要的资源是/news-info.php,cid=2&id=69是包含了两个参数 //Host是广告服务器我要访问的是哪个域名,服务器上往往是运行着多个网站,每个网站可能有不同的域名。虽然在代码的第一行里有域名, // 但是在连接的时候域名会被解析为ip地址。而作为服务器并不知道你要访问哪一个域名。 \”Host: www.12371yun.comn\” \”Connection: keep-aliven\” \”Pragma: no-cachen\” \”Cache-Control: no-cachen\” \”Upgrade-Insecure-Requests: 1n\” \”User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36n\” \”Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8n\” \”Accept-Encoding: gzip, deflaten\” \”Accept-Language: zh-CN,zh;q=0.9n\”; System.out.println(message); os.write(message.getBytes(\”UTF-8\”));//将报文数据通过输出流发送给服务器 //通过shutdownOutput高速服务器已经发送完数据,后续只能接受数据 socket.shutdownOutput();//结束输出流,就向通话完成后告诉对方:完毕 InputStream inputStream = socket.getInputStream(); //定义输出流,准备接收服务器返回的报文 byte[] bytes = new byte[1024]; int len; StringBuilder sb = new StringBuilder(); while ((len = inputStream.read(bytes)) != -1) { //注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8 sb.append(new String(bytes, 0, len,\”UTF-8\”)); } System.out.println(\”Response:rn================\”); System.out.println(sb); inputStream.close(); os.close(); socket.close(); }}

以上代码运行后会在服务器端输出如下结果:

以下为请求报文:GET http://12371yun.com/news-info.php?cid=2&id=69 HTTP/1.1Host: www.12371yun.comConnection: keep-alivePragma: no-cacheCache-Control: no-cacheUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9================以下为响应报文:HTTP/1.1 200 OKDate: Wed, 12 Jun 2019 05:02:48 GMTServer: Apache/2.2.21 (Win32) mod_ssl/2.2.21 OpenSSL/0.9.8t PHP/5.3.10X-Powered-By: PHP/5.3.10Keep-Alive: timeout=5, max=100Connection: Keep-AliveTransfer-Encoding: chunkedContent-Type: text/html;charset=utf-8<!DOCTYPE html><html lang=\”en\”><head> <meta charset=\”UTF-8\” /> <meta name=\”viewport\” content=\”width=device-width, initial-scale=1.0\” /> <meta http-equiv=\”X-UA-Compatible\” content=\”ie=edge\” /> <meta name=\”renderer\” content=\”webkit\”><title>话端阳 品传统,跟习近平总书记学中华文化传承之道 – 党建动态 – 五心鸿卓,智慧党建_专注智慧党务,智慧党建管理系统研发 – 鸿卓党建云平台</title><meta name=\”generator\” content=\”\” /><meta name=\”author\” content=\”\” /><meta name=\”keywords\” content=\”智慧党建,党建云,智慧党建系统,鸿卓党建云平台\” />//以下HTML内容省略

我们可以看到请求的报文内容是

GET http://12371yun.com/news-info.php?cid=2&id=69 HTTP/1.1Host: www.12371yun.comConnection: keep-alivePragma: no-cacheCache-Control: no-cacheUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9

这和浏览器检测到的请求内容是一样的:

「HTTP协议其实很简单.02」理解HTTP协议的第一行

而响应内容可以明显看出是分成了两部分,第一部分是:

HTTP/1.1 200 OK

Date: Wed, 12 Jun 2019 05:02:48 GMT

Server: Apache/2.2.21 (Win32) mod_ssl/2.2.21 OpenSSL/0.9.8t PHP/5.3.10

X-Powered-By: PHP/5.3.10

Keep-Alive: timeout=5, max=100

Connection: Keep-Alive

Transfer-Encoding: chunked

Content-Type: text/html;charset=utf-8

这一部分和请求的格式有些相似,一般我们称之为报头。

第二部分是:

<!DOCTYPE html><html lang=\”en\”><head> <meta charset=\”UTF-8\” /> <meta name=\”viewport\” content=\”width=device-width, initial-scale=1.0\” /> <meta http-equiv=\”X-UA-Compatible\” content=\”ie=edge\” /> <meta name=\”renderer\” content=\”webkit\”><title>话端阳 品传统,跟习近平总书记学中华文化传承之道 – 党建动态 – 五心鸿卓,智慧党建_专注智慧党务,智慧党建管理系统研发 – 鸿卓党建云平台</title><meta name=\”generator\” content=\”\” /><meta name=\”author\” content=\”\” /><meta name=\”keywords\” content=\”智慧党建,党建云,智慧党建系统,鸿卓党建云平台\” />//以下HTML内容省略

第二部分的内容和实际网页的源码则是一模一样的。

这就是一次HTTP请求的完整过程,与浏览器不同的是我们的程序最后显示的结果是源码,而浏览器收到这些响应的内容则是呈现出一个好看的页面。

另外,细心的同学可能会发现,F12工具中发现第一条请求之后会跟着发出了N多次请求,这就是浏览器在接收到第一个请求的响应之后,根据源码的内容将所需要的各类资源(js,css,png,jpg等)依次下载,最终将这些内容呈现为完整的网页。


看到这里我们再回到本篇文章的主题:第一行。 请求报文的第一行是:

GET http://12371yun.com/news-info.php?cid=2&id=69 HTTP/1.1

很明显这里面包含了三部分:

第一部分

GET:表示请求的类型.

HTTP协议中共定义了八种方法或者叫“动作”来表明对Request-URI指定的资源的不同操作方式,具体介绍如下:

OPTIONS:返回服务器针对特定资源所支持的HTTP请求方法。也可以利用向Web服务器发送\’*\’的请求来测试服务器的功能性。

HEAD:向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。

GET:向特定的资源发出请求。

POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的创建和/或已有资源的修改。

PUT:向指定资源位置上传其最新内容。

DELETE:请求服务器删除Request-URI所标识的资源。

TRACE:回显服务器收到的请求,主要用于测试或诊断。

CONNECT:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

虽然HTTP的请求方式有8种,但是我们在实际应用中常用的也就是get和post,其他请求方式也都可以通过这两种方式间接的来实现。

这些请求方式中GET请求的报文中是只有报头,没有body的。 而POST请求则是有body的。POST请求一般是用在向服务器提交一些数据的时候使用,例如:登录、注册帐号、填写一些数据等等。 我们来对比一下

POST http://127.0.0.1:80/auth/login.do HTTP/1.1Host: 127.0.0.1:80Connection: keep-aliveContent-Length: 66Origin: http://127.0.0.1:80X-Requested-With: XMLHttpRequestUser-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36Content-Type: application/json;charset=UTF-8Accept: */*{\”loginName\”:\”test\”,\”loginPwd\”:\”test\”,\”verifyCode\”:\”aujp0e\”}

这一段报文在最后还有一段json格式的数据。而GET请求是没有这最后的内容的。

第二部分

http://12371yun.com/news-info.php?cid=2&id=69

这部分表示你要请求服务器上哪个资源,可以是一个html、php、jsp、css、png等等,或者是一个目录。

那么如果我们想要请求一个css的请需要怎么修改这个报文呢?很简单,只需要把这一部分换成下面这样就可以了。

GET http://www.12371yun.com/css/index.css HTTP/1.1

实际上,要完整的呈现出一个页面,只有一次HTTP的请求过程是不够的,因为一个页面需要有基本的HTML代码,还有样式、js、以及很多图片,甚至还有从其它站点引入的js代码库等等,这些都需要浏览器在得到基本的HTML代码之后进行解析,然后依次将所有的资源请求回来之后才能完整的呈现。

第三部分

HTTP/1.1 这一部分表示http协议的版本

总结

这一篇文章我们用一个控制台程序去模拟浏览器进行了一次请求,通过这个程序我们可以完整的看到请求和响应的报文内容。

这个程序相当于是一个浏览端客户端,下一篇,我将讲解如何去写一个服务器端,然后用浏览器去访问我们的服务器端,去初步了解一下服务器端是如何处理HTTP请求的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2023年1月19日 上午9:06
下一篇 2023年1月19日 上午9:17

相关推荐