[ 网络 ] 应用层协议 —— HTTP协议

2023-11-18

目录

1.HTTP协议

1.1URL

urlencode和urldecode

2. HTTP协议格式

HTTP请求

HTTP响应

3.告知服务器意图的HTTP方法

GET:获取资源

POST:传输实体主体

GET和POST的区别

使用Cookie的状态管理

4.返回结果的HTTP状态码

状态码告知从服务器端返回的请求结果

2XX成功

3XX重定向

4XX客户端错误

5XX服务器错误

 5.HTTP的缺点


1.HTTP协议

应用层协议已经有大佬定义了一些现成的,有非常好用的应用层协议,我们可以直接参考使用。例如本篇所提到的HTTP(超文本传输协议)就是其中之一。

1.1URL

URL(统一资源定位符)就是我们俗称的"网址"

我们所常见到的网址:例如 https://www.baidu.com/ 是域名,这种字符串风格的域名,具有更好的字描述性。域名在解析时必须被转换成为IP地址,要访问网络服务,又必须具有port.

协议方案名和服务器端口号是强绑定的:

比如httpserver --- 80 ; httpsServer  --- 443 ; sshd --- 22

HTTP协议的本质是要获得某种"资源",比如我们请求百度的官网时,我们所获取的资源是百度首页的网页信息。我们可以理解为HTTP是 获取网页资源的(视频,音乐等)。HTTP是向特定的服务器向特定端口申请特定的"资源"的,获取到本地进行展示或者某种展示的。而对应服务器上,你所要的资源所在的位置就是URL中带层次的文件路径。

实际上,上网的大部分行为,都在进行这进程间通信。既然是通信,就是获取信息和发送信息。所以我们对应到生活中,大部分的上网行为,无非两种:

  1. 把服务器上面的资源数据拿到本地(短视频,小说等等)
  2. 把本都的数据推送到服务器(搜索,注册,登录,下单等)

urlencode和urldecode

在URL中,像 / ? 等这样的字符已经被URL当做特殊意义理解了。因此这些字符不能随意出现。

 比如:某个参数中需要带有这些特殊字符,就必须先对特殊字符进行转义。

转义规则:将需要转码的字符转为16进制,然后从右到做,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式。

我们可以看到 "C++" 中 "+"被转义成了 "%2B" 我们可以使用urlencode工具验证上述过程

UrlEncode编码/UrlDecode解码  |  urldecode就是urlencode的逆过程。

2. HTTP协议格式

HTTP请求

  •  首行:【方法】+【URL】+【版本】
  • Header:请求的属性,冒号分割的键值对;每组属性之间使用\n分割;遇到空行表示Header部分结束
  • Body:空行后面的内容都是Body.Body允许为空字符串.如果Body存在,则在Header中会有一个Content-Length字段用来表示Body的长度

常规情况下,HTTP(HTTPS)底层使用的传输层协议是TCP.

我们通过一段tcp套接字编程来查看HTTP请求格式

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>

using namespace std;
int main()
{
    int listen_sock = socket(AF_INET,SOCK_STREAM,0);
    if(listen_sock < 0){
        std::cout<<"socket error" <<std::endl;
        return 1;
    }

    struct sockaddr_in local;
    memset(&local,0,sizeof(local));

    local.sin_family = AF_INET;
    local.sin_port = htons(8082);
    local.sin_addr.s_addr = INADDR_ANY;

    if(bind(listen_sock,(struct sockaddr*)&local, sizeof(local))<0){
        std::cout<<"bind error" << std::endl;
        return 2;
    }
    if(listen(listen_sock,5) < 0){
        std::cout<<"listen error" << std::endl;
        return 3;
    }

    struct sockaddr_in peer;
    for(;;){
        socklen_t len = sizeof(peer);
        int sock = accept(listen_sock,(struct sockaddr*)&peer,&len);
        if(sock < 0){
            std::cout<<"accept error "<<std::endl;
            continue;
        }

        
        if(fork() == 0){
            if(fork() > 0) exit(0);
            close(listen_sock);

            char buffer[1024];
            recv(sock,buffer,sizeof(buffer),0);
            std::cout<<"###################HTTP request begin####################"<<std::endl;
            std::cout<< buffer << std::endl;
            std::cout<<"###################HTTP request end####################"<<std::endl;
            exit(0);
        }

        close(sock);
        waitpid(-1,nullptr,0);
    }
}

我们在直接打印出请求的格式

第一部分 首行:请求方法 请求url HTTP协议的版本

常用的请求方法:GET和POST (后面详解)

刚刚我们请求的是 /  . " / " 是Web根目录不是系统根目录。那我们也可以请求 /a/b/c/d.html 我们再次看看请求报文:

 

第二部分是一组Key:value的请求报头

请求报头是一堆Key: Value 请求属性,包括是否需要长链接,浏览器的编码类型,数据类型,我们想发送给服务器的相关信息等等.....通常存在多行,是一堆的Key: Value值

服务器端可以按行循环读取,一直读到\n (空行)就证明已经把报头读完了

第三部分:空行 

是报头和有效载荷的分离符,为了就是将报头和有效载荷进行分离

 前三部分都必须是按行方式陈列的

第四部分:请求正文(有效载荷)  ——非必须 | 可以没有

根据我们的需求,有时候我们需要登录账号和密码,个人信息,音乐,视频等等一般都是用户的相关信息或者数据。

以上就是HTTP协议的请求(HTTP request)。

HTTP响应

  • 首行: 【版本号】 + 【状态码】 + 【状态码解释】
  • Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束
  • Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度; 如果服务器返回了一个html页面, 那么html页面内容就是在body中.

HTTP响应也是由4部分组成,其中响应正文也是可以被省略的。客户端如何判断已经将response报头读取完毕呢,仍然是客户端可以循环按行读取,知道读取到空行。

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <fstream>

using namespace std;
int main()
{
    int listen_sock = socket(AF_INET,SOCK_STREAM,0);
    if(listen_sock < 0){
        std::cout<<"socket error" <<std::endl;
        return 1;
    }

    struct sockaddr_in local;
    memset(&local,0,sizeof(local));

    local.sin_family = AF_INET;
    local.sin_port = htons(8083);
    local.sin_addr.s_addr = INADDR_ANY;

    if(bind(listen_sock,(struct sockaddr*)&local, sizeof(local))<0){
        std::cout<<"bind error" << std::endl;
        return 2;
    }
    if(listen(listen_sock,5) < 0){
        std::cout<<"listen error" << std::endl;
        return 3;
    }

    struct sockaddr_in peer;
    for(;;){
        socklen_t len = sizeof(peer);
        int sock = accept(listen_sock,(struct sockaddr*)&peer,&len);
        if(sock < 0){
            std::cout<<"accept error "<<std::endl;
            continue;
        }

        
        if(fork() == 0){
            if(fork() > 0) exit(0);
            close(listen_sock);

            char buffer[1024];
            recv(sock,buffer,sizeof(buffer),0);
            // std::cout<<"###################HTTP request begin####################"<<std::endl;
            // std::cout<< buffer << std::endl;
            // std::cout<<"###################HTTP request end####################"<<std::endl;

#define PAGE "./wwwroot/index.html"
            
            std::ifstream in(PAGE);
            if(in.is_open()){
                in.seekg(0,std::ios::end);
                size_t len = in.tellg();
                in.seekg(0,std::ios::beg);

                char *file = new char[len];
                in.read(file,len);
                in.close();

                std::string status_line = "http/1.0 200 OK\n";
                std::string response_header = "Content-Length: "+std::to_string(len);
                response_header+="\n";
                std::string blank = "\n";

                send(sock,status_line.c_str(),status_line.size(),0);
                send(sock,response_header.c_str(),response_header.size(),0);
                send(sock,blank.c_str(),blank.size(),0);

                send(sock,file,len,0);
                delete[] file;
            }
            close(sock);
            exit(0);
        }

        close(sock);
        waitpid(-1,nullptr,0);
    }
}

  

3.告知服务器意图的HTTP方法

在众多的HTTP方法中最常用的是GET和POST方法,因此在此我们对GET和POST进行详细了解

GET:获取资源

GET方法是用来请求访问已被URL识别的资源。指定的资源经服务器端解析后返回响应内容。

我们也可以使用Postman工具抓取HTTP请求

POST:传输实体主体

POST方法是用来传输实体的主体

虽然用GET方法也可以传输实体的主体,但是一般不用GET方法进行传输,而是用POST方法。虽然POST的功能和GET很相似,但是POST的主要目的并不是获取响应的主体内容。

GET和POST的区别

  • GET方法可以带参,参数在URL " ?"的后面
  • POST方法通过正文传参
  • GET方法传参不私密
  • POST方法因为通过正文传参,所以相对私密一些

GET通过url传参,POST通过正文传参,所以一般一些大的内容都是通过POST传参。

使用Cookie的状态管理

HTTP是无状态协议,它不对之前发生过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求管理。那么我们在日常上网的过程中,假设要求登录认证的Web页面本身无法进行状态的管理(不记录已登录的状态),那么每次跳转新页面的时候都要再次登录,或者每次请求报文中附加参数来管理登录状态。那么这对我们用户是非常不友好的,就相当于我们每次登录C站我们都要进行登录认证。因此Cookie技术就是通过在请求和响应报文中写入Cookie信息来控制客户端的状态。

Cookie会根据从服务器端发送的响应报文内的一个叫Set-Cookie的首部字段信息,通知客户端保存Cookie。当下次客户端再往服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。服务器端发现过来的Cookie后,会检查究竟是从哪一个客户端的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。

举例:我们用B站来进行举例。

我只要登录过B站之后,再之后再次登录B站时会自动登录我的账号, 点击网址左边的锁,就会看到Cookie,点进去就会看到当前页面下的Cookie信息,我们全部进行删除后点击完成,再次刷新该页面,就发现无法找到之前的登录信息了。登录后再次查询发现Cookie信息被重新填写上了。

 

 

4.返回结果的HTTP状态码

HTTP状态码负责表示客户端HTTP请求的返回结果,标记服务器端的处理是否正常,通知出现的错误等工作。

状态码告知从服务器端返回的请求结果

状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求还是出现了错误。

状态码的类别

2XX成功

2XX的响应结果表明请求被正常处理了。

例如:

  1. 200 OK表示从客户端发来的请求在服务器端被正常处理了。
  2. 204 No Content 表示服务器接受的请求已成功处理,但在返回的响应报文中不含有实体的主体部分,也就是说请求处理成功但是没有资源可以返回。因此返回204响应后浏览器的显示页面不会发生更新。

3XX重定向

  1. 301 Moved Permanently 永久重定向。该状态码表示请求的资源已被分配了新的URL,以后应使用现在所指的URL。
  2. 302 Found 临时重定向。该状态码表示请求的资源已被分配了新的URL,希望用户本次能使用新的URL访问。
    1. 302和301状态码相似,但是302状态码代表的资源不是永久移动,只是临时性质的。换句话说,302的资源对应的URL将来还有可能发生变。
        if(fork() == 0){
            if(fork() > 0) exit(0);
            close(listen_sock);

            char buffer[1024];
            recv(sock,buffer,sizeof(buffer),0);
            //重定向到腾讯网
            std::string response = "HTTP/1.1 301 Permanently Moved\r\n";
            response += "Location: https://www.qq.com/\r\n"; 
            response += "\r\n";
            send(sock, response.c_str(), response.size(), 0);
            close(sock);
            exit(0);
        }

当服务器启动之后在浏览器输入ip:port后按下回车发现URL自动跳转到了腾讯网

  

4XX客户端错误

  1. 403 Forbidden 表示请求资源的访问被服务器拒绝了。服务器端没有必要给出拒绝的详细理由。
    1. 发生403的原因:未获得文件系统的访问授权,访问权限出现某些问题(从未授权的发送源IP地址试图访问)
  2. 404 Not Found 表示服务器上无法找到请求的资源。除此之外,也可能在服务器端拒绝请求且不想说明理由时使用。

5XX服务器错误

5XX的响应结果表名服务器本身发生错误

  1. 500 Internal Server Error 表示服务器端在执行请求时发生了错误。也可能是Web应用存在的Bug或某些临时的故障。

 5.HTTP的缺点

HTTP主要有如下不足之处:

  1. 通信使用明文(不加密),内容可能会被窃听
  2. 不验证通信方的身份,因此有可能遭遇伪装
  3. 无法证明报文的完整性,所以有可能已经遭到篡改

因此解决如上三个不足之处正是HTTPS的主要功能,因此HTTPS = HTTP+加密+认证+完整性保护。具体3个功能的实现细节,将单独整理成一篇博客HTTPS

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[ 网络 ] 应用层协议 —— HTTP协议 的相关文章

  • 使用意图过滤器从 URL 打开 Android 应用程序不起作用

    我有一个 Android 应用程序 人们用它来替代网站 因此 当用户遇到网站的 URL 时 我想为他们提供在我的应用程序中而不是在浏览器中 打开 URL 的选项 换句话说 我希望出现弹出窗口 让他们在我的应用程序和浏览器 可能还有其他应用程
  • 如何将 POST 请求内容保存为 .NET 中的文件 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我有一个客户端应用程序POST请求a
  • 有没有办法测量 Java (Servlet) I/O 流量?

    我尝试做的是使用以下代码实现 servlet 过滤器 int up request getContentLength if HttpServletRequest request getQueryString null up Math max
  • 从express.js 中删除所有标头

    我正在创建一个页面 其中有一些数据可以由另一个设备解析 我曾经使用 php 执行此操作 但现在将其移至 Node js 我需要从页面中删除所有标题 这样我就只有我的输出 此输出是对 GET 请求的响应 此刻我有 HTTP 1 1 200 O
  • 使用传输编码分块的 HTTP 响应中的最大块大小是多少?

    The w3 org RFC2616 http www w3 org Protocols rfc2616 rfc2616 sec3 html sec3 6 1似乎没有定义块的最大大小 但是如果没有最大块大小 则没有空间用于块扩展 必须有一个
  • Jsoup http 日志记录

    有没有办法记录http请求和响应 我们假设以下请求 Connection Response res Jsoup connect LOGIN URL HERE data user USER pass PASS method Connectio
  • 如何在没有 (L)GPL 库的情况下在 Python 中创建双重身份验证 HTTPS 客户端?

    客户端和服务器都是内部的 各自都有一个由内部CA签名的证书和CA证书 我需要客户端根据服务器拥有的 CA 证书来验证服务器的证书 它还应该将其证书发送到服务器进行身份验证 The urllib2手册说不执行服务器身份验证 PycURL是一个
  • 在Java中解析包含multipart/form-data请求体的字符串

    问题陈述 我认为标题说明了一切 我正在寻找解析 a 的方法String包含 multipart form data HTTP 请求的正文部分 IE 字符串的内容看起来像这样 xyzseparator blah Content Disposi
  • “双点”可以作为 URL 路径部分的一部分吗

    在 URL 中使用父目录双点是否有效且安全 如下例所示 http example com path to file jpg RFC3986 https www rfc editor org rfc rfc3986定义 URI 它描述了路径如
  • Angular4如何使用flatMap链接forkJoin

    我所处的情况是 我需要进行 5 个可以并行执行的 http 调用 在这五个调用之后需要执行另一个 http 调用 我在前 5 个中使用了 forkJoin 但我不知道如何链接 flatMap 或其他函数 forkJoin firstObse
  • 如何使用独立的 Jetty 进行服务器推送

    我正在尝试使用独立的 Jetty 在静态网站上测试服务器推送功能 我的网站由一个index html 1个CSS 一堆图像组成 目录结构为 Album index html style css images image 1 png a se
  • HTTP 和 HTTPS iframe

    我正在创建一个小部件 我想允许其他人使用它 这iframe通过 HTTP 加载 但我想允许用户通过 HTTPS 登录 即通过 SSL 发送登录请求 同源策略中允许这样做吗 即 场景是用户可以将我的 JavaScript 集成到他们的网站 小
  • 由于请求的资源上不存在“Access-Control-Allow-Origin”标头,无法获取与 Axios 的链接请求

    我正在尝试使用 cryptocompare api 来获取 axios 的 coindata 列表 但我不知道如何解决这个问题 我相信这是一个 CORS 问题 但我不确定 完整错误如下 加载失败https www cryptocompare
  • OkHttp如何获取Json字符串?

    Solution 这是我这边的一个错误 正确的方法是响应 body string 以外响应 body toString 我使用 Jetty servlet URL 是http 172 16 10 126 8789 test path jso
  • 通过 https 负载均衡器的 WCF http 服务

    我有一个可以通过 http 端点访问的 WCF Web 服务 现在 该服务应通过 https 与负载均衡器一起发布 客户端是通过 svcutil exe 在 Net 中创建的 但 Java 客户端也需要 WSDL 我的理解是 Web 服务在
  • 如何让 Sinatra 通过 HTTPS/SSL 工作?

    正如标题所示 谷歌没有提供任何与此相关的有用信息 如何为 Sinatra 应用程序设置和配置 HTTPS SSL 如何创建 HTTPS 路由 我以前从未在我的应用程序中使用过 HTTPS 也没有调整 Rack 其他内容的经验 所以我很欣赏详
  • 外部依赖错误的 HTTP 状态代码

    当服务器与外部 API 通信出现问题时 返回的正确 HTTP 状态代码是什么 假设客户端向我的服务器 A 发送有效请求 然后 A 查询服务器 B 的 API 以便执行某些操作 然而 B 的 API 当前抛出 500 错误或因某种原因无法访问
  • 在处理程序之后访问 HTTP 请求上下文

    在我的日志记录中间件 链中的第一个 中 我需要访问一些在链下游的某些身份验证中间件中编写的上下文 并且仅在处理程序本身执行之后 旁注 需要首先调用日志记录中间件 因为我需要记录请求的持续时间 包括在中间件中花费的时间 此外 当权限不足时 身
  • 是否可以修改 $_SESSION 变量?

    恶意用户是否可以将 SESSION 在 php 中 变量设置为他想要的任何值 很大程度上取决于您的代码 有一点非常明显 SESSION username REQUEST username
  • 从 HTTP 登录到 HTTPS

    我的网站默认使用 HTTP 我确实有一个启用 HTTPS 的证书 但只有其上的某些区域强制建立安全连接 登录是通过 Ajax 处理的 我想开始使用 SSL 即使请求来自 HTTP 我尝试强制请求的地址具有 HTTPS 并且它完美地回复 然而

随机推荐

  • Jupyter远程配置

    安装Jupyter pip install jupyter 生成默认配置文件 jupyter notebook generate config 生成密钥 python gt gt gt from notebook auth import p
  • 【React】单页面应用限制多开登录

    react 单页面应用限制多开登录 情景 测试小姐姐提了一个 BUG 在同一浏览器中打开两个页面 两个页面分别登录不同的账号 A 页面先登录A B 页面再登录B 此时回到 A 页面 交互时账号数据应该刷新为 B 登录的账号 分析 这个问题
  • 怎么设置权限?后台管理系统中的功能权限和数据权限设置

    一 功能级 页面级 权限 不同的用户 角色 登录到管理系统后 看到的功能不一样 思路 前端进入登录页面 前端发送请求给后端 后端验证用户名和密码是否正确 如果验证通过 需要根据用户所属的角色查他对应功能 path 响应给前端 前端接收到后端
  • RK3568 CAN驱动更新说明

    RK3568 CAN问题 同时收发数据一段时间 几秒钟 can出现错误收发功能异常 必须重新down up恢复正常 内核更新rockchip canfd c iopoll h 配置Networking support gt CAN bus
  • 学习笔记-Matlab算法篇-图与网络

    图与网络 01基本概念 介绍 图分为无向图和有向图 一个无向图 undirected graph G是由一个非空有限集合 V G 和V G 中某些元素的无序对集合E G 构成的二元组 记为G V G E G V G 称为顶点集 E G 称为
  • openGL使用assimp加载fbx格式三维模型

    前言 前面的文章中有讲过assimp加载obj三维文档格式 如果想要加入纹理还得配合对应的mtl格式和png格式才能加入纹理 今天来说下使用assimp加载fbx格式的三维模型 先看下运行效果 使用fbx模型 1 assimp库下载以及配置
  • Cocos2d-Lua(Quick-Cocos2d-x)集成第三方SDK(一)

    在我们实际开发过程中 经常会遇到需要使用第三方SDK的情况 比如我们常用的 友盟 TalkingData之类的统计分析SDK 移动MM 电信爱游戏之类的计费SDK 个推 百度推送之类的推送SDK 诸如此类的在iOS平台也有一大堆 那么在使用
  • Python27编译成pyd, 遇到error: Unable to find vcvarsall.bat

    我目前遇到2种情况 前提安装了 Python27 Cython setup py from setuptools import setup from Cython Build import cythonize setup ext modul
  • Kubernetes 集群部署 ------ 二进制部署(二)

    单节点 https blog csdn net Yplayer001 article details 104234807 先具备单master1节点部署环境 三 master02部署 优先关闭防火墙和selinux服务 在master01上
  • SQL中GROUP BY用法示例

    概述 GROUP BY我们可以先从字面上来理解 GROUP表示分组 BY后面写字段名 就表示根据哪个字段进行分组 如果有用Excel比较多的话 GROUP BY比较类似Excel里面的透视表 GROUP BY必须得配合聚合函数来用 分组之后
  • react项目按需加载报错 .libraryName is not a valid Plugin property

    babel presets react app plugins import libraryName antd style true 原配置如上会报错 libraryName is not a valid Plugin property g
  • Linux-MySQL 5.7.30安装与配置及开机自启

    Linux MySQL5 7 30安装配置 1 准备 1 1 检测系统是否自带MySQL 1 2 如果有 则使用下面命令进行删除 1 3 删除成功后 查询所有Mysql对应的文件夹 1 4 删除上面查找的所有文件夹 2 安装 2 1 使用X
  • java 调用C#的webservice

    import java rmi RemoteException import java util regex Matcher import java util regex Pattern import javax xml rpc Servi
  • TPS-1教学:TPS-1主控MCU程序软件移植指南

    TPS 1教学 TPS 1主控MCU程序软件移植指南视频 TPS 1教学 TPS 1主控MCU程序软件移植指南 电子发烧友网
  • vue项目部署到服务器

    启动和打包 进入项目目录 cd 进入到你项目的根目录 安装依赖 npm install 强烈建议不要用直接使用 cnpm 安装 会有各种诡异的 bug 可以通过重新指定 registry 来解决 npm 安装速度慢的问题 npm insta
  • Codeup(云效)手把手教部署SpringCloud项目到私有主机

    博主介绍 小黄鸭技术 擅长领域 Java 实用工具 运维 系列专栏 开发工具 Java之路 八股文之路 如果文章写作时有错误的地方 请各位大佬指正 一起进步 欢迎大家点赞 收藏 评论 支持博主 开通云效 上传代码仓库 配置SSH公钥或者是H
  • 在 openEuler 20.03 LTS SP1 中安装 JupyterLab

    目录 一 安装 openEuler 20 03 LTS SP1 1 1 Hyper V 虚拟化环境设置 1 2 安装配置 二 升级 Python 到 3 9 1 2 1 安装开发包 2 2 安装 LibreSSL 替代 OpenSSL 非必
  • Error in v-on handler (Promise/async): “Error: Request failed with status code 500“

    Error in v on handler Promise async Error Request failed with status code 500 点击确定按钮 添加数据 POST请求 报了错 发现是这个POST请求需要传参 传对象
  • 远程命令执行/命令注入 之 命令连接符

    目录 一 理论 二 实践 windows 10 a b a b a b a b kali linux a b a b a b a b 一 理论 远程命令执行可以用到的命令连接符 windows系统和linux系统各有4个 其中3个是共有的
  • [ 网络 ] 应用层协议 —— HTTP协议

    目录 1 HTTP协议 1 1URL urlencode和urldecode 2 HTTP协议格式 HTTP请求 HTTP响应 3 告知服务器意图的HTTP方法 GET 获取资源 POST 传输实体主体 GET和POST的区别 使用Cook