php企业网站论文网上购物网站开发的背景
web/
2025/9/30 23:57:24/
文章来源:
php企业网站论文,网上购物网站开发的背景,更改wordpress主题字体颜色,关键词排名优化软件策略1. 认识HTTP协议
HTTP#xff08;Hyper Text Transfer Protocol#xff09;协议又叫做超文本传输协议#xff0c;是一个简单的请求-响应协议#xff0c;HTTP通常运行在TCP之上。
超文本的意思就是超越普通的文本#xff0c;http允许传送文字#xff0c;图片#xff0c…1. 认识HTTP协议
HTTPHyper Text Transfer Protocol协议又叫做超文本传输协议是一个简单的请求-响应协议HTTP通常运行在TCP之上。
超文本的意思就是超越普通的文本http允许传送文字图片视频音频等协议我们前面也说过就是一种约定。
HTTP协议在应用层主要是解决如何处理对端发送过来的数据关于对端数据如何发送过来丢包了怎么办等问题不是应用层要考虑的在传输层网络层数据链路层会帮我们解决这些问题他只关心如何处理对端数据。 所以站在应用层的角度来看就是双方的应用层之间直接进行通信 2. 认识URL
URL叫做统一资源定位符 平时我们俗称的 网址 其实就是说的 URL。一个URL通常由以下几个部分构成 协议方案名最常见的就是http和https登录信息包含用户名和密码但是一般不会在URL中体现出来服务器地址其实就是IP地址只不过是被DNS服务解释成了域名服务器端口号一般不用在URL中体现出来因为当我们使用某种协议时该协议实际就是在为我们提供服务现在这些常用的服务与端口号之间的对应关系都是明确的所以我们在使用某种协议时实际是不需要指明该协议对应的端口号的因此在URL当中服务器的端口号一般也是被省略的。带层次的文件路径我们需要访问的资源在服务器的哪个位置例如上面的/dir/index.htm意思就是我们要访问/dir/index目录下的.htm文件。而 /dir 并不是从系统根目录开始的而是从web根目录开始服务器会自动在为 /dir 添加文件路径查询字符串就是我们要给服务器传递的参数中间以分隔。片段标识符对资源部分的补充 举个例子我们使用百度搜索http 显示的URL 我们对其划分 https就是协议方案名服务器地址是www.baidu.com文件路径是/s后面的就是查询字符串了也就是要传递给服务器的参数我们仔细观察会发现查询字符串中有一个wdhttp其实就是我们刚才要搜索的内容
2.1 urlencode和urldecode
像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.比如, 我们使用百度搜索?fsda* 显示的wd我们会发现除了?被转化成了%3F之外其他字符都能成功显示出来。
转义的规则如下:
将需要转码的字符转为16进制然后从右到左取4位(不足4位直接处理)每2位做一位前面加上%编码成%XY格式
urlencode就是将特殊字符进行转义编码而urldecode就是将转义后的特殊字符转化回去。解码。 3. HTTP协议格式
HTTP是应用层协议主要是分析对端传来的数据进行分析得出你想要的资源并且返回给你。例如上面的例子我们使用百度搜索http的过程百度的服务器在应用层分析出我们想要搜索的内容是http服务器经过比较复杂的一系列操作之后将结果再返回给我们。这种模式我们可以称为cs模型c就是客户端通常指的是我们client用户使用者s就是server服务端提供服务也可以是bs模型因为用户一般都是浏览器通过浏览器访问目标资源。
HTTP通过是基于TCP的而TCP是面向字节流的在传输数据过程中所有数据都是粘在一起的无法区分报文与报文之间的间隔我们要通过协议的方式解决这个问题而HTTP就是已经制定好比价h成熟的协议了。所以我们也要学习一下给服务端发送请求报文的格式与收到服务端响应报文的格式。
3.1 HTTP请求报文格式 请求行: [请求方法] [url] [版本]请求报头: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束空行标识报文读取结束请求正文: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度; 下面是几种比较常见的请求方法 其中最重要的两个就是GET和POST方法。
注意这里的url是web根目录并不是Linux系统根目录可以是机器上任何一个目录由我们自己指定。例如我将来将所有的资源都保存在wwwroot目录下。我们在写服务端的时候让默认路径
std::string defaultpath ./wwwroot;
浏览器给我们发送的url被提取之后我们直接在url前面添加defaultpath。例如我们默认访问的是 / 在添加之后就会变成
std::string url ./wwwroot/;
我们后续可以进行处理每个目录下我们都设置一个index.html的文件作为这个目录的首页当我们查看url发现他是一个目录的时候就让他默认访问这个目录下的index.html文件。
所以我们的url是 / 但是最终访问的资源其实是
std::string url ./wwwroot/index.html;
这就是web根目录的作用可以在指定目录下进行资源查找。 3.2 HTTP响应报文格式 状态行[http版本][状态码][状态码描述]响应报头请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束空行遇到空行表示响应报头结束。响应正文响应正文允许为空字符串如果响应正文存在则响应报头中会有一个Content-Length属性来标识响应正文的长度。 状态码和状态码描述用于描述请求的结果 常见的状态码以及状态码描述 [200 OK 成功] 请求正常被服务器处理[204 Not Content] 请求处理成功但是没有资源可返回相应报文中不含实体的主体部分另外也不允许返回任何实体浏览器返回的页面不发生更新一般在只需要客户端给服务端发消息而对客户端不需要发送新内容的情况下使用[206 Partial Content] 表示客户端进行了范围请求客户端只要某一部分的信息服务器成功执行了这部分的GET请求相应报文中包含Content-Range指定范围的实体内容[301 Moved Permanently] 永久性重定向,资源移动会更新浏览器书签, 相应状态码返回时所有浏览器都会把POST改成GET,并删除请求报文主体之后请求会自动再次发送[302 Found] 临时性重定向资源移动不会更新浏览器书签,相应状态码返回时所有浏览器都会把POST改成GET,并删除请求报文主体之后请求会自动再次发送[303 See Other] 资源的URI已经更新临时按新的URI进行访问使用GET请求获取相应的资源,相应状态码返回时所有浏览器都会把POST改成GET,并删除请求报文主体之后请求会自动再次发送[304 Not Modified] 自从上次请求后请求的网页未修改过。服务器返回此响应时不会返回网页内容。如果网页自请求者上次请求后再也没有更改过您应将服务器配置为返回此响应称为 If-Modified-Since HTTP 标头。服务器可以告诉 Googlebot 自从上次抓取后网页没有变更进而节省带宽和开销。返回时不包含任何请求的主体部分304和重定向无任何关系[307 Temporary Redirect] 临时重定向和302有相同的含义[400 Bad Request] 请求报文中存在语法错误服务端无法理解需修改请求的内容后再次发送请求,浏览器会像对待200一样对待该状态码[401 Unauthorized] 发送的请求需要有通过HTTP认证的认证信息。另外若之前已经已经进行过一次请求则表示用户认证失败, 当浏览器初次接收到401响应会弹出认证用的对话窗口[403 Forbidden] 服务器拒绝请求该资源, 或者表示未获取文件系统的访问授权访问权限出现某些问题, 服务器端可以说明拒绝的理由并返回给客户端展示[404 Not Found] 表示请求的资源在服务器上不存在或未找到所以无法提供给客户端。[500 Interval Server Error] 服务器在执行请求时发生故障, 也可能是web应用存在的bug或者某些临时故障[503 Service Unavailable] 服务器目前超负载正忙着呢,正在进行停机维护现在无法处理请求 在HTTP请求报文和响应报文中都包含了版本这一字段为什么要交互版本呢 请求报文发送的是客户端的http版本响应报文发送的是服务端的版本主要是为了能让不同版本的客户端都能享受到服务。客户端告诉服务端自己的版本服务端就可以为客户端提供适合他的版本的服务。例如微信最初的版本是没有微信支付的功能的如果我们一直使用的是最初版本不更新的话那么服务端就不会给我们提供微信支付功能只有把微信更新到一定版本才会支持。 3.3 报文中的常见字段 Content-Type数据类型text/html等。Content-Length正文的长度。Host客户端告知服务器所请求的资源是在哪个主机的哪个端口上。Connection字段最常用于客户端要求服务器使用 TCP 持久连接以便其他请求复用。User-Agent声明用户的操作系统和浏览器的版本信息。Referer当前页面是哪个页面跳转过来的。Location搭配3XX状态码使用告诉客户端接下来要去哪里访问。Cookie用于在客户端存储少量信息通常用于实现会话session的功能。 1.Host字段用于指明我们要访问资源的位置。 Host: www.A.com
2.Content-Length正文的长度
Content-Length: 100
3.Content-Type请求资源的类型例如我们要请求一张网页就是html。
Content-Type: text/html
4.Connection用于客户端要求服务器使用 TCP 持久连接以便其他请求复用。 http/1.0采用的是短链接的方式即浏览器客服端发起请求建立连接服务器构建响应之后立刻就会断开连接。但是对于一个网页包含的元素较多则需要建立多次连接频繁的建立连接断开连接的资源消耗比较大TCP需要经历3次握手4次挥手的过程。
http/1.1采用长连接即建立连接后不再断开客户端一次可以发多个请求。当连接双方超过一定时间没有数据交互时就会自动断开连接。如果Connection字段是keep-alive就代表是长连接。 Connection: keep-alive5.User-Agent声明用户的操作系统和浏览器的版本信息。
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0当我们想下载一个软件时默认都会下载适合我们电脑型号的版本就是因为我们会发送我们电脑的操作系统版本信息。
6.Cookie和Session
HTTP 是一种不保存状态 即无状态stateless 协议。 HTTP 协议自身不对请求和响应之间的通信状态进行保存。 也就是说在 HTTP 这个级别 协议对于发送过的请求或响应都不做持久化处理。
但是我们今天登录csdn后把浏览器关闭甚至关机重启后我们会发现我们的账号还是登录上的并没有要求我们再次输入密码这就是Cookie技术。 我们可以在对应网站查看 cookie如果把Cookie删除下次登录就需要重新输入账号密码了。关于Cookie的内容后面会详细说先简单了解一下。 3.4 如何将报头和有效载荷分离
http协议中每一行的内容都以 \r\n 结尾所以我们可以读取到 \n 说明我们读取到了这一行。我们可以使用按行读的方式如果读到了某一行是空行说明我们读到了一个完整报文剩下的内容直到读到 \n 都是正文内容也可以通过读取报头中的Content-Length字段提取正文的大小进行读取。 4. HTTP请求与响应
4.1 获取浏览器的请求报头
我们可以使用代码来获取浏览器的请求报头看一下。
#include iostream
#include fstream
#include string
#include cstring
#include unistd.h
#include sys/wait.h
#include sys/socket.h
#include sys/types.h
#include netinet/in.h
#include arpa/inet.hint main()
{//创建套接字int listen_sock socket(AF_INET, SOCK_STREAM, 0);if (listen_sock 0){std::cerr create socket error! std::endl;return 1;}std::cout create socket success std::endl;//绑定struct sockaddr_in local;memset(local, 0, sizeof(local));local.sin_family AF_INET;local.sin_port htons(8080);local.sin_addr.s_addr htonl(INADDR_ANY);if (bind(listen_sock, (struct sockaddr*)local, sizeof(local)) 0){std::cerr bind error! std::endl;return 2;}std::cout bind success std::endl;//监听if (listen(listen_sock, 10) 0){std::cerr listen error! std::endl;return 3;}std::cout listen success std::endl;//启动服务器struct sockaddr peer;memset(peer, 0, sizeof(peer));socklen_t len sizeof(peer);while (true){int sock accept(listen_sock, (struct sockaddr*)peer, len);if (sock 0){std::cerr accept error! std::endl;continue;}if (fork() 0){close(listen_sock);if (fork() 0){exit(0);}char buffer[1024];recv(sock, buffer, sizeof(buffer), 0); //读取HTTP请求std::cout --------------------------http request begin-------------------------- std::endl;std::cout buffer std::endl;std::cout ---------------------------http request end--------------------------- std::endl;close(sock);exit(0);}close(sock);waitpid(-1, nullptr, 0);}return 0;
}GET / HTTP/1.1
Host: 123.60.181.162:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0
Accept: text/html,application/xhtmlxml,application/xml;q0.9,image/avif,image/webp,image/apng,*/*;q0.8,application/signed-exchange;vb3;q0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q0.9,en;q0.8,en-GB;q0.7,en-US;q0.6
这里可以看到我们我们收到的报文就是这个格式其实GET就是请求方法 / 是请求的urlhttp/1.1是版本。值得一提的是 / 指的是web根目录并不是Linux系统根目录可以是机器上任何一个目录由我们自己指定。
请求报头中的字段都是 KV格式例如Host表示被请求资源方的IP和端口其中Host就是属性名后面的才是真正的IP和端口。而这个请求报文中并没有出现Content-Length属性说明没有正文部分的内容。
4.2 给浏览器发送响应报头
在收到浏览器的请求之后我们可以构建一个报头给浏览器响应回去。
#include iostream
#include fstream
#include string
#include cstring
#include unistd.h
#include sys/wait.h
#include sys/socket.h
#include sys/types.h
#include netinet/in.h
#include arpa/inet.hint main()
{// 创建套接字int listen_sock socket(AF_INET, SOCK_STREAM, 0);if (listen_sock 0){std::cerr create socket error! std::endl;return 1;}std::cout create socket success std::endl;// 绑定struct sockaddr_in local;memset(local, 0, sizeof(local));local.sin_family AF_INET;local.sin_port htons(8080);local.sin_addr.s_addr htonl(INADDR_ANY);if (bind(listen_sock, (struct sockaddr *)local, sizeof(local)) 0){std::cerr bind error! std::endl;return 2;}std::cout bind success std::endl;// 监听if (listen(listen_sock, 10) 0){std::cerr listen error! std::endl;return 3;}std::cout listen success std::endl;// 启动服务器struct sockaddr peer;memset(peer, 0, sizeof(peer));socklen_t len sizeof(peer);while (true){int sock accept(listen_sock, (struct sockaddr *)peer, len);if (sock 0){std::cerr accept error! std::endl;continue;}if (fork() 0){close(listen_sock);if (fork() 0){exit(0);}char buffer[1024];recv(sock, buffer, sizeof(buffer), 0); // 读取HTTP请求std::cout --------------------------http request begin-------------------------- std::endl;std::cout buffer std::endl;std::cout ---------------------------http request end--------------------------- std::endl;// 读取index.html文件std::ifstream in(./index.html);if (!in.is_open()){std::cerr open file error std::endl;}std::string line;std::string file;while (std::getline(in, line)){file line;}// 构建HTTP响应std::string status_line http/1.1 200 OK\n; // 状态行std::string response_header Content-Length: std::to_string(file.size()) \n; // 响应报头std::string blank \n; // 空行std::string response_text file; // 响应正文std::string response status_line response_header blank response_text; // 响应报文// 响应HTTP请求send(sock, response.c_str(), response.size(), 0);close(sock);exit(0);}close(sock);waitpid(-1, nullptr, 0);}return 0;
}代码的逻辑很简单只是在接受到浏览器的请求报头之后打开当前目录下的index.html文件。index.html文件内容也很简单 我们来测试一下最终的效果。 服务器启动浏览器访问 请求报文如图所示因为是长连接所以有多个http请求。客户端请求后服务端会构建http响应。 最终也是成功收到了我们想要的html资源。 4.3 使用telnet
我们可以使用telnet命令进行抓包给服务器发送请求并接受服务器的响应 可以看到我们现在给服务器响应的内容只有请求行和一个空行。 按下回车之后就可以看到响应报头了包括状态行响应报头以及正文部分正文部分对应的内容其实就是html网页浏览器会自动帮我们进行渲染 我们打开开发者模式就可以看到这段html代码就是服务端的响应正文。 5. GET和POST方法 前面说过请求方法中最重要的两种方法就是GET和POST。 首先我们要认识上网行为无非就是两种 1.从网络中获取数据。 2.将数据上传到网络上 而将数据上传到网络我们通常使用的是GET获取POST方法而从网络中获取数据一般使用的是GET方法。
两者的主要区别是
GET方法是通过url传参的。POST方法是通过正文传参的。
我们先了解一下html中的表单。 我们先简单写一个表单的代码
htmlhead/headbodyh1Hello World/h1form action/a/index.html methodGETuser:brinput typetext namexnamebrpassword:brinput typepassword nameypwdbr/brinput typesubmit valueLog in/form/body
/html
最终效果 我们可以看到表单form中有一个属性method就是GET说明此时我们使用的是GET方法。GET方法使用url传参。 当我们使用我们在表单中输入了账号和密码之后点击Log in登录 我们会发现url中果然有一个xnamezhangsan和ypwd12345这都是我们刚才输入的值。 所以服务端自然也可以根据url提取出账号和密码了。
如果是POST方法呢POST方法通过正文传参 首先url中没有数据了。 我们可以看到在最后的正文部分果然是有账号和密码的。
所以我们可以知道GET和POST的区别在于传参的位置不同GET方法通过url传参POST方法通过正文传参 那么问题来了GET方法很容易被看到POST方法不容易被看到那么POST方法是不是比GET方法更安全 其实无论是GET方法还是POST方法都是不安全的。POST方法虽然不容易被看到但是不排除会被抓包数据都是明文的还是不安全只能说POST方法比GET方法更加私密。安全这方面要看加密和解密。 6. Cookie和Session
HTTP 是无状态协议 它不对之前发生过的请求和响应的状态进行管理。 那么现在会出现一个问题。假设我们要登录某视频网站观看VIP用户才能看的电影《战狼》 此时已经认证成功接下来应该是登录此账号然后观看但是因为跳转到登录页面并且是在登录页面输入的账号密码返回到主页面时并不会保存你的账号密码因为http是无状态的。这样用户就永远无法成功登录账号。
由此引入了Cookie技术Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息 通知客户端保存 Cookie。 当下次客户端再往该服务器发送请求时 客户端会自动在请求报文中加入 Cookie 值后发送出去。服务器端发现客户端发送过来的 Cookie 后 会去检查究竟是从哪一个客户端发来的连接请求 然后对比服务器上的记录 最后得到之前的状态信息 加入了Cookie之后上面的例子变成了 在第一次收到http响应时会保存一个Cookie文件此后访问服务端时都会默认加上Cookie信息。 内存级别 / 文件级别 Cookie文件分为内存级别和文件级别内存级别顾名思义就是保存在内存当中当我们关机重启之后就不存在了此时我们需要重新登录而文件级别就是写入磁盘当中关机重启之后依然存在 Cookie被盗问题 在有了以上认识后我们会想到如果别人盗取了我们的cookie文件怎么办他就知道了我们的账号和密码了。
此时就可以引入SessID的概念了。 服务端在收到用户名和密码后会用用户名和密码生成一个独一无二的SessionID并把SessionID和用户名密码关联起来然后将SessionID返回给用户用户将来访问时只使用SessionID。 这种方法无法解决Cookie被盗的问题但是相对来说比较安全用户的用户名和密码无法被盗取。
我们可以做一个测试
std::string status_line http/1.1 200 OK\n; // 状态行
std::string response_header Content-Length: std::to_string(file.size()) \n; // 响应报头
response_header Set-Cookie: namezhangsan;
response_header Set-Cookie: possword123456;
std::string blank \n; // 空行
std::string response_text file; // 响应正文
std::string response status_line response_header blank response_text; // 响应报文
构建的响应报头如上所示。 可以看到我们的网站的Cookie文件当中果然存在了用户名和密码。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/84720.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!