当前位置: 首页 > news >正文

HTTP协议---详细讲解

目录

一、HTTP协议

1.http 

2.url

url的组成:

url的保留字符:

3.http协议格式​编辑

①http request

②http response

4.对request做出响应

5.GET与POST方法

①GET

②POST

7.HTTP常见Header

①Content-Type:: 数据类型(text/html等)在上文我们使用过。

②Content-Length: 正文的长度。

③Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上。

④User-Agent: 声明用户的操作系统和浏览器版本信息。

⑤referer: 表示当前页面是从哪个页面跳转过来的。

⑥Location: 搭配3xx状态码使用, 告诉客户端接下来要去哪里访问。

⑦Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能。


一、HTTP协议

1.http 

        上篇文章我们体验了定制协议的繁琐,这次我们来讲述下真正成熟的有很多人使用的协议,例如:http、https、smtp、dns等。

        Http协议:超文本传输协议。

        客户端通过使用Http协议来向服务端获取资源。

2.url

        我们俗称的“网址”就是url。

协议方案名:上例是http://,表示使用http协议。后面我会讲到https,这是http协议的加密版本,现在多数都使用的都是https。

登录信息:我们这次不考虑,一般会省略掉,在正文中携带登录信息。

服务器地址:是资源所在的网站名或服务器的名字,又称为域名。在网络通信中域名必须被转换为IP地址。

端口号:HTTP 协议的默认端口是80,如果省略了这个参数,服务器就会返回80端口的网站。在上上一篇文章中讲到网络之间的通信就是进程之间的通信,通过域名(IP地址)+端口号的方式就可以在全网中确定唯一一个进程。我们发现一些url会缺省port,一般由浏览器自动添加,而这些url对应的port都是公开的,一旦服务上线端口号就已经确定,httpserver->80,httpsserver->443,sshd->22。

文件路径:资源在服务器的位置。

查询字符串:提供给服务器的额外信息。

片段标识符:也叫做锚点,锚点是网页内部的定位点,浏览器加载页面之后,回滚到锚点锁定位的位置。

url的组成:

        26个英文字母 10个阿拉伯数字 连词号(-)句典(.) 下划线(_)

url的保留字符:

        有10个保留字符,只能在给定位置出现。        

        如果在其他位置去使用保留字符,就必须使用转义形式。

        其中罗列一部分,都是关于特殊符号的转义,那我要在url中体现汉语怎么办?

        我们可以现场搜索一下,见见实际情况。 

        我们会发现汉字也会被转义,转义的规则为:将需要转码的字符转换为16进制,从右到左取四位,每两位做一位,前面加上%,编码成%XY格式。 

3.http协议格式

        注意:

        method为请求方法,常见的get方法、post方法。

        key:空格value

        http/1.1为当前版本为1.1

        现在我们可以通过上节课代码,我们运行server,通过浏览器来访问我们的server,将接收到的东西打印出来,我们就可以真正的见到http request。

①http request

        在浏览器中输入你主机的IP地址:你的server绑定的端口号。

        上图中关于服务器版本的信息,当我们换个浏览器使用就会有不同的效果。

        如图我是用iphone的safari浏览器依据我们的ip与port来访问的。

         至于浏览器会表现出如此现象是因为我们做为服务器没有向浏览器响应发送任何东西。

        上文的tcpserver的代码是上篇文章写的,很是臃肿,于是我删删减减,得到了simple版本。

void handlerHttpRequest(int sock)
{cout<<"++++++++++++++++++++++++"<<endl;char buffer[1024];ssize_t sz = read(sock, buffer, sizeof(buffer));if (sz > 0){cout << buffer << endl;}
}class Tcpserver
{
public:Tcpserver(uint16_t port, const string &ip = ""): _sock(-1), _port(port), _ip(ip){_quit = false;}~Tcpserver(){if (_sock >= 0)close(_sock);}public:void init(){_sock = socket(AF_INET, SOCK_STREAM, 0);if (_sock < 0){exit(1);}struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(_port);_ip.empty() ? INADDR_ANY : (inet_aton(_ip.c_str(), &local.sin_addr));if (bind(_sock, (const sockaddr *)&local, sizeof(local)) < 0){exit(2);}if (listen(_sock, 5) < 0){exit(3);}}void start(){signal(SIGCHLD, SIG_IGN);while (!_quit){struct sockaddr_in peer;socklen_t len = sizeof(peer);int servicesock = accept(_sock, (struct sockaddr *)&peer, &len);if (_quit)break;if (servicesock < 0){cerr << "accept error ..." << endl;continue;}int clientport = ntohs(peer.sin_port);string clientip = inet_ntoa(peer.sin_addr);pid_t pid = fork();assert(pid != -1);if (pid == 0){if (fork() > 0)exit(4);handlerHttpRequest(servicesock);exit(0);}close(servicesock);wait(nullptr);}}void safequit(){_quit = true;}private:int _sock;uint16_t _port;string _ip;// 安全退出bool _quit;
};Tcpserver *svrp = nullptr;
void sighandler(int sig)
{if (sig == 3 && svrp != nullptr)svrp->safequit();cout << "server quit" << endl;
}

         上文我们可以看到http request的响应代码。接下来我们看一下http response的响应代码。

②http response

        接下来,我们可以通过命令行的方式向baidu发送request获得response。

        进入telnet后按ctrl+],再按回车输入GET / HTTP/1.1,然后按两下回车。 

4.对request做出响应

        上文我们对浏览器的request并没有做出任何响应,server仅仅是将接收到的http request中的内容,下文我们将对request做出响应。当然不是无所依据的responce,我们可以参照上文百度做出的responce。

         这个函数的参数神似我们使用过的write,将flags设置为0,就和write等价。

代码:

void handlerHttpRequest(int sock)
{char buffer[1024];ssize_t sz = read(sock, buffer, sizeof(buffer));if (sz > 0){cout << buffer << endl;}// response  string response;response += "HTTP/1.0 200 OK\r\n"; // response请求行response += "\r\n"; // 本行为\r\n为请求报头与正文的分界线 请求报头暂且为空response += "Hello world!"; // 正文send(sock,response.c_str(),response.size(),0);
}

结果: 

         单纯Hello world!有点单一,我们可以让它成为这个网页的大标题,这个工作将由浏览器接收到我们的正文部分然后渲染就可以得到效果了。

代码:

response += "<html><h1>Hello world!</h1></html>"; // 正文

结果:

        再次升级,我们将响应报头完善下。

        Content-Type 内容类型 指出我们正文所对应的类型。

        上文中的正文内容为.html,Content-Type就应该填text/html。

        具体的对照类型,可以看这篇博客。

 代码:

    // response  string response;response += "HTTP/1.0 200 OK\r\n"; // response请求行response += "Content-Type: text/html\r\n";response += "\r\n"; // 本行为\r\n为请求报头与正文的分界线 请求报头暂且为空response += "<html><h1>Hello world!</h1></html>"; // 正文

        结果跟上文无疑。

        如何保证将响应行与响应报头读完整呢?读到空行就可以保证。那如何保证正文读取完整呢?这就是响应报头中的内容来保证的。

        Content-Length负责记录正文的长度。

代码:

    // responsestring html = "<html><h1>Hello world!</h1></html>";string response;response += "HTTP/1.0 200 OK\r\n"; // response请求行response += "Content-Type: text/html\r\n";response += ("Content-Length: " + to_string(html.size()) + "\r\n");response += "\r\n"; // 本行为\r\n为请求报头与正文的分界线 请求报头暂且为空response += html;   // 正文

结果:这次通过使用telnet来检验成果,浏览器不会显示。

        作为建设服务器的人员将网页构建的代码写到服务器中,是否有点挫,那应该放在什么地方?先前我们在讲url的时候提到过文件路径,由客户端依据文件路径请求资源,服务器依据请求放回资源。所有我们的html等资源都是放在文件里。 

        至于文件路径是否要从linux根目录中开始写,写到目标文件为止,会写出很长一段文件路径。其实不用,如果客户端要访问a/b/c.html,我们能说a文件就是linux的根目录吗,不能,这是web根目录,具体可以看下方代码。

    request = "/a/b/c.html";path = "linux/server/web"; // web根目录path += request; ->linux/server/web/a/b/c.html // 最终的文件路径

        这次我们将我们的html放在文件中,由客户端申请客户端返回。

        我们的主页在当前工作路径下的wwwroot里。

代码:

#define CRLF "\r\n"
#define SPACE " "
#define SPACE_LEN strlen(SPACE)
#define HOME_PAGE "index.html"
#define WEB_ROOT "./wwwroot"
// 负责将http_request中的文件路径提取出来
string getPath(string http_request)
{ssize_t pos = http_request.find(CRLF);if (pos == string::npos)return "";string request_line = http_request.substr(0, pos);// GET /a/b/c http/1.1ssize_t firstSpace = request_line.find(SPACE);if (firstSpace == string::npos)return "";ssize_t secondSpace = request_line.rfind(SPACE);if (secondSpace == string::npos)return "";string path = request_line.substr(firstSpace + SPACE_LEN, secondSpace - (firstSpace + SPACE_LEN));if (path.size() == 1 && path[0] == '/')path += HOME_PAGE; // 如果只发了/ ,我们就将我们网址的主页返回过去return path;
}
// 负责打开文件将文件的内容读取出来
string readFile(const string &path)
{ifstream in(path, std::ifstream::binary);if (!in.is_open())return "404";string content;string line;while (getline(in, line))content += line;in.close();return content;
}
void handlerHttpRequest(int sock)
{char buffer[10240];ssize_t sz = read(sock, buffer, sizeof(buffer));if (sz > 0){cout << buffer;}string path = getPath(buffer);cout << "path->" << path << endl;string resource = WEB_ROOT;resource += path;cout << "resource->" << resource << endl;string html = readFile(resource);string response;response += "HTTP/1.0 200 OK\r\n"; // response请求行response += "Content-Type: text/html\r\n";response += ("Content-Length: " + to_string(html.size()) + "\r\n");response += "\r\n"; // 本行为\r\n为请求报头与正文的分界线 请求报头暂且为空response += html;   // 正文send(sock, response.c_str(), response.size(), 0);
}
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>http server</title>
</head>
<body><h3>TEST</h3><p>Hello World!</p>
</body>
</html>

 telnet中的结果:无论是请求/ 还是/index.html 结果都一样因为我们当前只有一个主页。

web中的结果: 

5.GET与POST方法

①GET

        下面我们来鉴别POST方法与GET方法的区别。

        我们都知道上网的行为一般分两种:

        1.从远端获取资源到本地 使用GET方法  //GET / HTTP/1.1 

        2.将本地的资源上传到远端 可以使用POST方法也可以使用GET方法。

        我们这次使用表单将信息填写,然后先用GET方法发送。

代码:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>http server</title>
</head><body><h3>TEST</h3><p>Hello World!</p><form action="abc/qwe/index.html" method="get">Username: <input type="text" name="user"><br>Password: <input type="password" name="passwd"><br><input type="submit" value="Submit"></form>
</body></html>

现象:我们将信息填入点击submit

         提交过后会发现会出现404,那是因为网页代码中我们指定将数据提交的网址(abc/qwe/index.html)在服务器中并不存在。

         我们主要来分析下当前的url。

        我们会发现在HTTP协议中GET方法会以明文的方式 将我们对应的参数信息,拼接到url中。

②POST

        下面来看看POST方法。

        我们会发现GET方法中会将信息拼接在url中,而POST方法不一样,它是将信息拼接到http requset中的正文中。

总结:

        1. GET方法通过url传参

        2. POST方法通过正文传参

        3. GET方法传参不私密

        4. POST方法传参通过正文,相对私密。至于为什么不说安全与不安全,HTTP协议在某种角度来说就是不安全的,不管通过GET还是POST方法提交数据都会通过抓包等软件获取到url或者正文,所以说都是不安全的,下面我们会学习HTTPS现在主流安全可靠的协议。

        5. 网页中内容较少一般通过GET方法传参,内容较多通过POST方法传参。

6.HTTP状态码

        最常见的状态码,比如200(OK),404(Not Found),403(Forbidden),302(Redirect,重定向),504(Bad Gateway)。 

        我们向服务器申请一个并不存在的资源将会返回什么状态码呢?

        会返回4XX,因为客户端申请的资源并不存在,服务器就算穷举也找不到,所以这是客户端出错。

        什么时候会返回5XX呢?

        客户端申请一些任务,服务器去执行,在其中会申请内存,线程,进程等手段执行任务,当服务器中一些资源到达载荷就会返回5XX。

        我们主要研究下3XX。     

        客户端向服务端发起请求,服务端响应中携带301 || 302 和new url,浏览器就会自动跳转到新的服务端去获得资源。        

        我们通过我们简单的代码,也可以验证下。

代码:

void handlerHttpRequest(int sock)
{char buffer[10240];ssize_t sz = read(sock, buffer, sizeof(buffer));if (sz > 0){cout << buffer;}string response = "HTTP/1.1 302 Moved Temporarily\r\n";response += "Location: www.baidu.com\r\n";response += "\r\n";send(sock, response.c_str(), response.size(), 0);
}

现象:

        至于为什么没有显示我们重定向之后的页面呢,因为浏览器作为客户端并行的向我们的服务端发送请求,服务端则是向每一个请求都返回重定向,所以会显示出图片中的错误。

        当然我们此时也没有完全写对,Location之后一定跟的是网址。写成www.baidu.com只是目前的站内跳转,要实现不同的域也就是服务器跳转,代码要变成:

    response += "Location: https://www.baidu.com/\r\n";

现象:将IP地址和端口输入回车之后,就会跳转到我们重定向之后的界面。

        

        什么时候会用到301或者302呢?

        301作为永久重定向,一般是在网站更换网址时使用,比如,当时的url取的很随意当想改变跟换一个更好听的时候,会发现当前访问旧网址的人很多,为了避免再换url时损失大量用户,可以在用户访问旧url时,使用永久重定向跳转到新的url。

        302作为临时重定向,当该网站临时维护时,不想拒绝访问的用户,可以用到临时重定向使网站跳转到另一个可以提供服务的网站。

                    

7.HTTP常见Header

①Content-Type:: 数据类型(text/html等)在上文我们使用过。

②Content-Length: 正文的长度。

③Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上。

④User-Agent: 声明用户的操作系统和浏览器版本信息。

        我们通过Windows环境下的浏览器打开qq的官网观察下载页面,会发现下载页面直接为Windows版本下载。

         通过手机浏览器打开qq的官网,会发现下载页面会变为qq手机版。

        这是依据什么来改变响应界面呢,与User-Agent这个信息密切相关。

⑤referer: 表示当前页面是从哪个页面跳转过来的。

⑥Location: 搭配3xx状态码使用, 告诉客户端接下来要去哪里访问。

⑦Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能。

        在讲Cookie之前我们要知道HTTP协议的特点之一是无状态,什么是无状态呢,简单就是HTTP协议本事并不会记录你请求资源的行为,请求过了再请求HTTP协议本事并不会记录你当前已经请求过了。但是我们当前所知道的浏览记录等信息都是显而易见被记录下来的信息,这些信息都是依靠HTTP周边策略来实现的,比如说Cookie策略。

        这个Cookie在哪其作用呢?

        像我们每次登入一个常用的网站,关闭之后再次进入,会发现登陆的账号还在保持登陆状态,这就是cookie起了作用,当我们禁止cookie就会发现每次登陆之后关闭再打开,会让你再次登陆,并不会延续你上次登陆的用户。

        我们尝试讲Cookie体现在代码中

代码:

 现象:

        一般流程为我们客户端讲登陆信息输入,登录信息就会被记录到服务器中,当再次访问网站时, 登陆信息就会通过Set-Cookie发送到客户端。

        当然Cookie不仅仅是存在于服务端,也有可能存在于浏览器维护的文件中。

        我的登录信息这么简单的存储在本地文件中,那木马病毒等不正当手段随便就可以获取我的登陆信息岂不是我的上网安全岌岌可危,所以我们要使用Cookie和Session组合起来的方式来保证安全。

        客户端输入登陆信息,然后将登陆信息发给服务端,服务端根据登陆信息形成Session文件,该文件的文件名具有唯一性,该文件名被称为session_id。服务端再将该session_id发给客户端,客户端会将session_id写入本地的cookie中。在cookie中的表现只出现session_id。下次登陆时客户端就会将session_id发送给服务端,服务端依据session_id来判断是否有权利享有对应的资源。

        那这个session_id会不会也会被轻易盗取,也是会的,这个问题没有根本解决。但是session_id丢掉之后,你丢掉的只是session_id,你的信息会保存在服务端。大型的服务端有很不错的防护系统。至于更多的知识,感兴趣的同学可以去了解一下更细致的讲解。

关于Cookie和Session的要点:

        Cookie的Expires属性指定了cookie的生存期,默认情况下coolie是暂时存在的,他们存储的值只在浏览器会话期间存在,当用户退出浏览器后这些值也会丢失,如果想让cookie存在一段时间,就要为expires属性设置为未来的一个过期日期。现在已经被max-age属性所取代,max-age用秒来设置cookie的生存期。因此当没有设定过期时间时,则退出当前会话时cookie失效。

        Session可以存放各种类别的数据,相比只能存储字符串的cookie,能给开发人员存储数据提供很大的便利。

        SessionID可以存储每个用户Session的代号,是一个不重复的长整型数字。

        单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

        目前此篇文章就写到这里,关于HTTPS协议将会在下篇与大家见面,如有错误请指出,感谢观看,我们下次再见。

相关文章:

HTTP协议---详细讲解

目录 一、HTTP协议 1.http 2.url url的组成&#xff1a; url的保留字符&#xff1a; 3.http协议格式​编辑 ①http request ②http response 4.对request做出响应 5.GET与POST方法 ①GET ②POST 7.HTTP常见Header ①Content-Type:: 数据类型(text/html等)在上文…...

Syntax-Aware Aspect-Level Sentiment Classification with PWCN 论文阅读笔记

一、作者 Chen Zhang, Qiuchi Li, and Dawei Song. 2019. Syntax-Aware Aspect-Level Sentiment Classification with Proximity-Weighted Convolution Network. In Proceedings of the 42nd International ACM SIGIR Conference on Research and Development in Information …...

hadoop考试应急

概述 四大特点&#xff1a;大量化、快速化、多元化、价值化 关键技术&#xff1a;采集、存储管理、处理分析、隐私和安全 计算模式&#xff1a;批处理、流、图、查询分析计算 Hadoop处理架构 了解就好 2007年&#xff0c;雅虎在Sunnyvale总部建立了M45——一个包含了4000…...

【React】Hooks

&#x1f6a9;&#x1f6a9;&#x1f6a9; &#x1f48e;个人主页: 阿选不出来 &#x1f4a8;&#x1f4a8;&#x1f4a8; &#x1f48e;个人简介: 一名大二在校生,学习方向前端,不定时更新自己学习道路上的一些笔记. &#x1f4a8;&#x1f4a8;&#x1f4a8; &#x1f48e;目…...

升级Room引发的惨案!!

kotlin升级 在升级kotlin的时候&#xff0c;直接升级到大版本的kotlin&#xff08;比如1.7以上&#xff09;&#xff0c;直接报错&#xff0c;只是报错不知道原因。 koltin Release details 后来把koltin版本改成1.6.0&#xff0c;报如下的错&#xff0c;我们才知道gradle是需…...

RPC框架:一文带你搞懂RPC

RPC是什么&#xff08;GPT答&#xff09; ChatGPT回答&#xff1a; RPC(Remote Procedure Call)是一种分布式应用程序的编程模型&#xff0c;允许程序在不同的计算机上运行。它以一种透明的方式&#xff0c;将一个程序的函数调用定向到远程系统上的另一个程序&#xff0c;而使…...

电子招标采购系统源码—企业战略布局下的采购寻源

​ 智慧寻源 多策略、多场景寻源&#xff0c;多种看板让寻源过程全程可监控&#xff0c;根据不同采购场景&#xff0c;采取不同寻源策略&#xff0c; 实现采购寻源线上化管控&#xff1b;同时支持公域和私域寻源。 询价比价 全程线上询比价&#xff0c;信息公开透明&#xff0…...

P16 激活函数与Loss 的梯度

参考&#xff1a;https://www.ngui.cc/el/507608.html?actiononClick这里面简单回顾一下PyTorch 里面的两个常用的梯度自动计算的APIautoGrad 和 Backward, 最后结合 softmax 简单介绍一下一下应用场景。目录&#xff1a;1 autoGrad2 Backward3 softmax一 autoGrad输入 x输出损…...

ThinkPHP5美食商城系统

有需要请私信或看评论链接哦 可远程调试 ThinkPHP5美食商城系统一 介绍 此美食商城系统基于ThinkPHP5框架开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。用户注册登录后可购买美食&#xff0c;个人中心&#xff0c;评论和反馈等&#xff…...

Vue3 - $refs 使用教程,父组件调用获取子组件数据和方法(setup() / <script setup>)

前言 在 Vue2 中父组件使用 $refs 调用子组件数据和方法非常简单,但在 Vue3 中这种方法行不通了。 本文实现了 Vue3 中父组件使用 $refs 获取调用子组件数据和方法教程, 并且提供了 setup() 与 <script setup> 两种 “开发模式” 的示例代码,请根据需要进行选择。 网…...

华为OD机试 - 众数和中位数(Python)| 真题+思路+考点+代码+岗位

众数和中位数 题目 众数是指一组数据中出现次数多的数 众数可以是多个中位数是指把一组数据从小到大排列,最中间的那个数, 如果这组数据的个数是奇数,那最中间那个就是中位数 如果这组数据的个数为偶数,那就把中间的两个数之和除以 2 就是中位数查找整型数组中元素的众数并…...

一眼万年的 Keychron 无线机械键盘

一眼万年的 Keychron 无线机械键盘 一款好的键盘对于程序员或者喜欢码字的人来说是非常重要的&#xff0c;而最近博主入手了自己的第一款机械键盘——Keychron 无线机械键盘。 机械键盘特点 有独立轴体&#xff0c;通过两个簧接触&#xff0c;来触发信号&#xff0c;价格相对贵…...

自动化测试高频面试题(含答案)

Hello&#xff0c;你们的好朋友来了&#xff01;今天猜猜我给大家带来点啥干货呢&#xff1f;最近很多小伙伴出去面试的时候经常会被问到跟自动化测试相关的面试题。所以&#xff0c;今天特意给大家整理了一些经常被公司问到的自动化测试相关的面试题。停&#xff0c;咱先收藏起…...

3、按键扫描检测处理

说明&#xff1a;本文处理按键的短按、长按检测执行&#xff0c;非矩阵按键 硬件可以类似如下连接即可&#xff0c;无需放置上下拉电阻&#xff1b; 按键动作分长按、短按(弹起时执行)两种 按下不放执行长按&#xff0c;但松开按键时不予执行短按函数 多个按键可以同时操作 按…...

集中式存储和分布式存储

分布式存储是相对于集中式存储来说的&#xff0c;在介绍分布式存储之前&#xff0c;我们先看看什么是集中式存储。不久之前&#xff0c;企业级的存储设备都是集中式存储。所谓集中式存储&#xff0c;从概念上可以看出来是具有集中性的&#xff0c;也就是整个存储是集中在一个系…...

【机器学习数据集】如何获得机器学习的练习数据?

一、scikit-learn自带数据集Scikit-learn内置了很多可以用于机器学习的数据&#xff0c;可以用两行代码就可以使用这些数据。自带的小的数据集为&#xff1a;sklearn.datasets.load_<name>load_bostonBoston房屋价格回归506*13fetch_california_housing加州住房回归20640…...

【编程实践】使用 Kotlin HTTP 框架 Fuel 实现 GET,POST 接口 kittinunf.fuel【极简教程】

目录 Fuel 简介 实现代码 GET网络请求用法(有三种写法࿰...

大数据DataX(一):DataX的框架设计和插件体系

文章目录 DataX的框架设计和插件体系 一、DataX是什么...

软考高级信息系统项目管理师系列之十一:项目进度管理

软考高级信息系统项目管理师系列之十一:项目进度管理 一、进度管理领域输入、输出、工具和技术表二、项目进度管理1.项目进度管理过程2.项目进度管理三、项目进度管理过程1.项目进度管理2.工作包和活动3.活动清单4.活动属性5.项目进度网络图6.资源日历7.活动资源需求8.资源分解…...

vue2版本《后台管理模式》(下)

文章目录前言一、home 页以下都属于home子组件二、header 头部 组件二、Menu 页面三、Bread 面包屑四、Footer五 、分页器&#xff1a; Pageing![在这里插入图片描述](https://img-blog.csdnimg.cn/fbe9bb7e84a04ccda4d3fc9f4ab9c36b.png#pic_center)六、权限管理总结前言 这章…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重&#xff0c;适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解&#xff0c;并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...