
1.域名我们平时在浏览器输入 www.baidu.com 并回车地址栏会自动变成https://www.baidu.comwww.baidu.com 是域名https 是协议浏览器默认优先使用 HTTPS少数旧网站仍用 HTTP访问一个网站本质是访问服务器而访问服务器必须知道两个信息1. 服务器IP地址2. 端口号Port但我们在 https://www.baidu.com 里看不到IP也看不到端口这是为什么域名会自动解析成 IP域名只是方便人记忆计算机只认IP。我们可以在 cmd命令提示符中查询百度的IPping www.baidu.com会得到类似这就是百度服务器的真实IP。直接在浏览器输入39.156.70.239也能打开百度说明域名 方便记忆的别名最终会被DNS解析为IP端口号为什么看不见因为 HTTP 和 HTTPS 有默认端口浏览器会自动补全不需要手动写。规则固定HTTP 协议默认端口80HTTPS 协议默认端口443访问 http://www.baidu.com 等价于http://www.baidu.com:80访问 https://www.baidu.com 等价于https://www.baidu.com:443浏览器会自动匹配协议与端口所以我们看不到端口号。2.URL唯一资源定位符在我们平常说的网址就是URL。上面的域名就是一个服务器的名字而URL就是定位到服务器中的某一个具体信息。当我们访问b站的时候https://www.bilibili.com/b站的服务器地址就叫做域名。我们访问b站里面的具体某一个链接的时候。https://www.bilibili.com/c/dance/?spm_id_from333.1007.0.0这个就叫做URL用来表示一个资源的唯一地址。所以有了url那么所有网络上的资源图片音频等都可以使用唯一的一个\字符串\标识并且可以获取到那么下面我们来详细认识一下url的格式URL的格式那么第一个字段通常是https://或者http://格式是进行协议的选择然后冒号两个斜杠进行分隔第二个字段是登录信息目前几乎不使用了可以省略所以我们不关心然后分隔符也可省略第三个字段是服务器的地址即虽然填写的是一个域名但是我们要知道这个是可以被经过域名解析然后转化为服务的IP地址的然后分隔符是冒号通常冒号也可省略接下来就是服务器的端口号通常也可以省略因为浏览器已经将很多的常用服务器对应的端口号已经内置了接下来是 / 其中这个 / 我们称之为web根目录这个目录有可能是根目录同样也有可能是采用的相对路径的根目录那么 /dir/index.htm 我们称之为带层次的文件路径其实就是要访问的资源的存放路径。urlencodeURL编码和urldecodeURL解码像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义.转义的规则如下:将需要转码的字符转为16进制然后从右到左取4位(不足4位直接处理)每2位做一位前面加上%编码成%XY就会被编码为%2B去网络上面搜也会得到很多的编码和解码的工具。HTTP协议格式HTTP请求报文格式HTTP 请求等于4 部分1. 请求行2. 请求报头3. 空行4. 请求正文1. 请求行第一行格式固定方法 URL 版本\r\n例子GET /index.html HTTP/1.1\r\nMethodGET拿数据、POST传数据URL就是你前面学的那个地址版本HTTP/1.1最常用结尾必须 \r\n请求方法上面的请求方法中基本上面很多使用的都是GET和POST方法。GET方法查数据我们对于上一篇博客写的index.html进行修改!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleDocument/title /head body h1这是首页/h1 form action/A/hello.html methodget user: input typetext nameuserbr password: input typepassword namepasswdbr input typesubmit value提交 /form /body /html上面的代码意思也就是使用get方法通过输入账号密码之后点击提交给A/hello.html地址通过输入账号密码提交后。发现get方法回将账号密码通过和的方法添加在URL路径中。那么为什么返回的是404我们不是已经写了要提交给哪一个文件吗因为并没有对url进行解析所以如上图这里的文件路径就会连带我们提交的参数也算上所以这里自然会打开文件失败然后返回404如果想要正常解析的话应该将url进行按照?分隔符进行提参然后分隔分别得出正确的文件路径以及我们提交的参数。POST方法提交数据我们对于上一篇博客写的index.html进行修改!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleDocument/title /head body h1这是首页/h1 form action/A/hello.html methodpost user: input typetext nameuserbr password: input typepassword namepasswdbr input typesubmit value提交 /form /body /html上面的代码意思也就是使用post方法通过输入账号密码之后点击提交给A/hello.html地址通过输入账号密码提交后。发现可以成功跳转这是因为post方法是将账号密码放入到正文里面所以提交的URL路径可以被成功解析。GET和POSTGET 和 POST 都能提交参数核心区别只是参数存放位置不同GET把参数放在 URL 地址栏里提交POST把参数放在请求正文请求体里提交数据大小的限制GETURL 长度有限所以参数数量、大小都受限POST放在请求体理论上无大小限制隐私性GET参数直接显示在 URL 上别人一眼就能看到账号、密码完全不私密POST参数不在 URL 显示旁人看不到相对私密虽然GET 参数在 URLPOST 参数在请求体但是其实两种方法都是不安全的因为两者都在 HTTP 请求报文里都能被抓包工具抓到都是明文、都不安全。真正的安全靠的是 HTTPS 加密不是靠 POST。状态码HTTP 状态码一共分 5 大类从 1xx 到 5xx每一类含义固定1xx信息性状态码临时响应1开头的状态码属于临时通知。含义是服务器已经收到你的请求了正在处理你稍等不要断开。2xx成功状态码请求正常处理2开头代表请求成功服务器正常处理返回了你要的数据。最常见的就是200 OK表示一切正常完美响应。3xx重定向状态码作用是服务器告诉客户端你去访问另一个地址我这里不直接返回内容。放在后面说4xx客户端错误最常见的就是404表示客户端请求了不存在的路径资源。是客户端发的请求有问题服务器处理不了。5xx服务器错误5开头代表请求没问题但是服务器自己崩了、处理失败了。2. 请求报头一堆 Key: Value每个都是Key: Value\r\n的格式比较常用的字段有下面的几个Content-Type: 数据类型(text/html等)Content-Length: Body的长度Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上;User-Agent: 声明用户的操作系统和浏览器版本信息;referer: 当前页面是从哪个页面跳转过来的;location: 搭配3xx状态码使用, 告诉客户端接下来要去哪里访问;Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能;里面最重要的就是 Content-Length: 数字表示请求正文有多少字节一般GET取数据才会有Content-LengthPOST传数据一般没有。Location前面我们跳过了 3xx 状态码现在我们搭配响应报头 Location 一起来讲。3xx 状态码统一叫做重定向状态码它的核心作用就是让浏览器再发一次请求去访问另一个地址。什么是重定向 当有一个服务器升级、换域名、换地址了但是老用户并不知道服务器的地址的变化还在访问旧地址。这时候服务器不能直接返回内容而是要告诉浏览器“你别访问我了去新地址。”服务器就会返回一个 3xx 状态码在响应头里加一个 Location新网址浏览器收到后就会自动发起第二次 HTTP 请求去访问 Location 里的新地址。这就是重定向。301 永久重定向当旧地址彻底不用了以后永远用新地址当服务器访问旧网址的时候浏览器第一次访问收到了301也就重定向下次在访问的时候就会直接去新网址就不会再访问旧网址重新发送新的访问请求来访问新网址了。302 临时重定向旧地址只是暂时不能用临时跳去新地址以后还会换回来。浏览器每次访问都会访问旧网址重新发送新的请求来访问新网址。代码呈现我们就可以对之前的HTTP服务器的代码修改发送的响应状态码改为302重定向到百度的界面static void HandleHttp(int sockfd) { char buffer[10240]; ssize_t nread(sockfd,buffer,sizeof(buffer)-1); if(n0) { buffer[n]0; coutbufferendl; // string texthello world; HttpRequest req; req.Deserialization(buffer); req.parse(); req.DebugPrint(); string textReadHTMLContent(req.filepath_); // string responseHTTP/1.1 200 OK\r\n; string responseHTTP/1.1 302 Found\r\n; responseLocation:http://www.baidu.com\r\n; response\r\n; responsetext; send(sockfd,response.c_str(),response.size(),0); } close(sockfd); }我们修改了发送的响应报文所以无论访问的是服务器哪一个路径都会跳转到百度界面。CookieCookie 文件范围文件级和内存级当我们浏览器登入软件的时候会把我们输入的账号和密码存放在 Cookie 文件中如果存放在文件级的话我们关闭浏览器再打开就要重新输入了在内存级我们关机下次打开也会存在Cookie 文件是有过期时间的。cookie 文件里面一般都存有我们比较私密的信息如果我们不小心点取了某一个网页就会面临 cookie 文件被盗取和个人信息泄露的问题。session当用户第一次使用系统时需要进行注册。用户把自己的用户名 XXXX、密码 YYYY 提交给服务器服务器完成注册逻辑。为了不让密码明文传输、也不让密码存在 Cookie 里服务器会做一件关键事情使用 MD5 等摘要算法根据用户名、密码、时间戳等信息生成一段唯一的、不可逆的字符串这个字符串就叫 Session ID。Session ID 可以理解成用户的临时身份证、数据指纹。接下来服务器会把这个 Session ID 和对应用户的信息用户名、密码、用户ID、权限等管理起来。用户数据就会存在服务器不在客户端。然后服务器在给浏览器的 HTTP 响应报头中加入一个字段Set-Cookie浏览器收到了之后把 Session ID 保存到本地 Cookie 文件中。从此以后浏览器每次向服务器发 HTTP 请求都会自动带上 Cookie也就是自动带上这个 Session ID。服务器每次收到请求都会拿请求里的 Session ID去自己的 Session 存储里查。如果查到了说明用户登录过、合法登录成功。如果没查到 登录失败当 cookie 文件过期了就让你重新登录可以但是还是避免不了你的 cookie 文件被盗窃因为避免不了用户去点击其他的网站被黑客窃取到服务端也会对每次的登录进行检测比如你上次登录在一个地方下次就跑到几千公里外就会删除你的 session id 让你重新登录。3. 空行就是\r\n只有这一行什么都没有告诉浏览器报头结束正文开始4. 请求正文要上传的数据比如登录时需要填写的账号密码usertinganpassword123GET 一般没有正文POST 才有长度由 Content-Length 决定完整 HTTP 请求长这样GET /index HTTP/1.1\r\nHost: bilibili.com\r\nUser-Agent: xxx\r\n\r\n这里开始是正文前三行请求行 报头中间 \r\n空行分界线空行下面正文数据HTTP响应报文格式那么http响应也包含四部分分别是状态行响应报头空行响应正文那么也是同样的要求要求状态行响应报头空行全部都要以\r\n结尾那么我们主要讲解状态行状态行的字段中第一个字段是HTTP Version即http的版本同样的版本可以是1.0 1.1 2.0主流版本一般是1.1那么进行写入的时候需要加斜杠/即HTTP/1.1这种格式第二个字段是状态码例如200404等第三个字段是状态码的字符串形式的描述那么第二个字段和第三个字段相信大多数的读者友友都曾经见到过即对应右图的界面状态行的各个字段同样需要空格进行分隔并且状态行的结尾是\r\n。