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

【计网】【计网】从零开始学习http协议 ---理解http重定向和请求方法

在这里插入图片描述

去光荣地受伤,
去勇敢地痊愈自己。
--- 简嫃 《水问》---

从零开始学习http协议

  • 1 知识回顾
  • 2 认识网络重定向
  • 3 http请求方法
    • 3.1 http常见请求方法
    • 3.2 postman工具进行请求
    • 3.3 处理GET和POST参数

1 知识回顾

前面两篇文章中我们学习并实现了http协议下的请求与应答:

  • http请求包括四个部分:请求行 , 报头 , 空行 , 请求正文。请求行中的URL是客户端想要获取的资源,这是对于服务器来说最重要的部分,服务器后续通过URL在网络根目录中搜索对应的资源,然后通过应答报文返回。
  • http应答包括四个部分:状态行 , 报头 , 空行 , 应答正文。应答正文中包含从服务器返回的实际内容,如HTML页面、图片或其他数据。
  • 请求与应答中的报头都是用于传输请求和应答的一些基础信息,以键值对的形式储存。

http协议作为通信协议,必然要支持序列化与反序列化。我们需要做的是服务器的操作,只需要进行请求的反序列化和应答的序列化就可以了,请求的序列化和应答的反序列化是浏览器(客户端)需要考虑的。要做到序列化和反序列化需要按照请求和应答的结构,从字符串中读取分离出来,具体操作可以参考之前的文章:

  1. 【计网】从零开始学习http协议 — http的请求与应答
  2. 【计网】从零开始学习http协议 — 通过http实现客户端交互

实现了http协议中服务器的序列化和反序列化,接下来就可以加入一些资源来供客户端获取。
对于状态行的http版本与http状态码,我们也有了初步的了解:

  1. http版本:浏览器和服务端需要互相告诉各自的版本号,进而做到对应的处理!因为http协议会不断更新,不能保证对方是否更新协议!
  2. http状态码:状态码是服务器做出应答时根据数据处理的情况返回给浏览器。每个状态码对应一种情况!

2 认识网络重定向

状态码中3XX是代表重定向的:

状态码含义
301Moved Permanently 永久重定向
302Found 临时重定向
307Temporary Redirect 临时重定向资源到新位置
308Permanent Redirect 永久重定向资源到新位置

其中大部分使用301 302,307 308很少使用!我们介绍一下临时重定向和永久重定向。

首先,网络中的重定向和文件的重定向概念上比较类似。一般来说,我们访问对应的网址会直接找到对应的服务器进程。当这个服务器让课客户端重新进行请求另一个服务器时,此时就是重定向!

举个例子:学校南门口有一家非常好吃的饺子馆,小明经常去那里吃饭。后来因为道路施工问题,饺子馆搬到看学校北门口,并为了让老客户可以找到新地址,在原来门店贴上新地址。小明这天去了,看到了这个告示,就知道应该去北门口找到这家饺子馆,这就是重定向!以后小明在想去饺子馆应该去老地址还是新地址呢?
这就需要分两种情况:

  1. 如果饺子馆是临时搬到北门口,那么小明一个去原南门口的饺子馆看看,再来决定是否去北门口。
  2. 如果饺子馆是永久搬到北门口,那么下面不用犹豫,直接就去北门口就可以!

这里的两种情况就是临时重定向和永久重定向的区别:临时重定向只修改一次,下次客户端依然访问原网址。永久重定向会永久修改,下次客户端直接访问新地址!

实际应用中,也有实际的例子:

甲公司使用www.hello.com网址使用了很多年,积攒了很多用户。后来甲公司将公司网址改成了www.world.com
那么下一次老用户访问原网址时,对老客户进行重定向访问到新网址,并修改老客户中浏览器中的对应网址信息。这就是永久重定向!

永久重定向是给搜索引擎看的!每个搜索引擎都会抓取全国各个网站的网址信息,然后建立起键值对。每次搜索时就可以通过关键词搜索到对应的网站。这个抓取是不断进行的。当一个网站的网址永久更改时,在原网址设置重定向到新网址,客户端每次进到原网址都要进行一次重定向,每次都进行重定向就太麻烦了!所以浏览器发现永久重定向之后就会修改内部信息,下次就会直接访问到新网址!
在这里插入图片描述
我们可以在服务器中测试一下重定向!
我们在页面中加入一个测试重定向的链接,这个链接会请求/redir资源,这个资源实际上并不存在,只是用来进行是否进行重定向的判断依据!
在这里插入图片描述

这样点入链接之后,就会再次发送请求/redir这个资源,我们可以在处理时进行一个硬处理,当客户端访问这个资源时进行一个特殊处理:

	if (hreq.Path() == "wwwroot/redir"){// 进行重定向LOG(DEBUG, "进行重定向!!!\n");std::string redir_path = "https://www.qq.com"; // 重定向的新地址resp.AddCode(302, _code_to_desc[302]);resp.AddHeader("Location", redir_path);// resp.AddBody(content);}else{//...}

这样进行序列化返回给浏览器之后,浏览器会自动识别,然后就跳转到新的网址中了!!!
在这里插入图片描述
非常好玩,这个现象就是重定向!!!

3 http请求方法

3.1 http常见请求方法

在http请求中有请求行,请求行中有一个参数:请求方法_method。这个请求方法到底是干什么用的呢?

http中有以下请求方法:

请求方法方法说明适配HTTP版本
GET请求指定的资源。一般用于信息查询,不应产生副作用。HTTP/1.0
POST向指定的资源提交数据进行处理请求(例如提交表单或上传文件)。HTTP/1.0
PUT向指定资源位置上传其最新内容。HTTP/1.0
DELETE请求服务器删除Request-URI所标识的资源。HTTP/1.0
HEAD类似于GET请求,但响应体不会返回,用于获取报头信息。HTTP/1.0
OPTIONS用于描述目标资源的通信选项。HTTP/1.1
TRACE回显服务器收到的请求,主要用于测试或诊断。HTTP/1.1
CONNECT用于将连接改为管道方式的代理服务器。HTTP/1.1
PATCH对资源进行部分修改。HTTP/1.1

其中最常见的就是GET方法和POST方法。 平时使用浏览器一般都是获取资源,就是进行GET。有时也会进行登录注册,这时会向服务器发送资源,就是进行POST!那么浏览器是如何进行呢?
我们可以在服务器中加入打印客户端请求方法,这样我们可以看到:
在这里插入图片描述
可以看到只要是获取资源都是使用的GET方法!

3.2 postman工具进行请求

那我们可以进行GET方法了,怎么进行POST方法呢?可以使用postman这个工具:

Postman提供了一个直观的界面来构建HTTP请求,包括设置请求头、请求体、认证等。
Postman允许用户发送各种HTTP请求(如GET, POST, PUT, DELETE等)到API端点,并检查响应。它支持测试脚本,可以自动验证响应数据。

我们通过postman快速创建http请求,使用POST方法发送。
在这里插入图片描述
这样服务器就得到了POST方法的请求。
在这里插入图片描述

GET方法不光可以获取数据,也可以向服务器发送数据。POST方法也可以向服务器推送数据!
我们可以在postman中加入两个键值对:
在这里插入图片描述
这样我们再次请求时,就会发现我们可以通过url向服务器进行传参了!
在这里插入图片描述

我们在使用POST方法试一试,POST方法需要再请求的正文中加入参数:
在这里插入图片描述
这样服务器会得到一个请求,这个请求正文中包含了传入的参数!
在这里插入图片描述
总结:

  • GET方法一般用来获取静态资源,也可以通过URL向服务器传递参数。
  • POST方法可以通过http请求的正文来进行参数的传递。
  • URL传参,参数的体量一定不大;正文传参,参数的体量可以很大!

3.3 处理GET和POST参数

但是在用户的实际使用中,用户不可能像POSTMAN一样可以手动选择请求方法,那么实际应用中,是通过前端的form表单完成GET和POST请求!

    <div><!-- 默认就是GET --><form action="/login" method="POST">用户名: <input type="text" name="username" value="."><br>密码: <input type="password" name="userpasswd" value=""><br><input type="submit" value="提交"></form></div>

这里最后使用POST方法,因为使用GET方法,会将参数加入到URL中,这样其他人可以就能够看到用户和密码了,这样可不行!
在这里插入图片描述
那么服务器如何处理参数呢?这个action="/login" 又是什么含义呢?

  • 当使用POST方法时,参数是写在正文中的,那么直接直接按照规则进行解析就可以了!
  • 如果使用GET方法,参数是加在URL中的。如果不做处理,会影响我们后续的很多操作,所以需要对URL进行处理!将真正的URL提取出来,并在正文中储存参数!
        // 解析参数 --- 忽略大小写进行比较if (strcasecmp(_method.c_str(), "GET") == 0){//寻找 ?auto pos = _url.find(arg_sep);//包含?说明带参数if(pos != std::string::npos) {_req_body_text = _url.substr(pos + arg_sep.size());_url.resize(pos);}}
    

这样不管是使用的什么方法传递的参数,我们都可以通过正文中获取参数了!

接下来我们来看action="/login",这个资源我们并不存在啊?这个action需要怎么处理呢?

我们在httpserver中加入一系列的服务名称与服务函数的哈希对应。

using func_t = std::function<HttpResponse(HttpRequest)>;std::unordered_map<std::string , func_t> server_list;void InsertService(const std::string servicename , func_t f){//加入网络根目录!std::string s = prefixpath + servicename;_server_list[s] = f;}

那么对于"/login"我们可以插入一个:

hserver.InsertService("/login" , login);

那么服务器可以在处理请求之后,进行特殊处理。识别出来action是"/login"时,就可以去执行func_t函数,然后可以返回对应的应答!

        if (hreq.Path() == "wwwroot/redir"){// 进行重定向LOG(DEBUG, "进行重定向!!!\n");//...}else if (!hreq.GetRequestBody().empty()){if (IsServiceExists(hreq.Path())){resp = _server_list[hreq.Path()](hreq);}}

这样就实现了对action的处理!!!所以http不光可以处理静态资源,也可以处理函数!

我们就可以设计一个处理login的方法:


HttpResponse Login(HttpRequest &req)
{HttpResponse resp;std::cout << "外部已经拿到了参数了: " << std::endl;req.GetRequestBody();std::cout << "####################### " << std::endl;resp.AddCode(200, "OK");resp.AddBody("<html><h1>result done!</h1></html>");// username=helloworld&userpasswd=123456//可以进行很多种的操作!// 1. pipe// 2. dup2// 3. fork();// 4. 其他进程执行 -> exec* -> python, PHP, 甚至是Java!return resp;
}

这样我们能处理不同的action了:
在这里插入图片描述
通过这种方式,我们可以通过回调函数func_t进行可以进行很多操作了:

  1. pipe创建管道
  2. dup2进行重定向
  3. fork创建子进程
  4. exec*系列进行进程替换

因为C++语言处理业务并不擅长,但是c++处理底层十分快速!所以我们可以通过管道或者新的进程将数据交给python或者java这样的web语言来处理,然后在将数据返回给服务器,服务器处理好之后将http应答交给客户端!
这样服务器中各种语言的关系我们也就大概了解了!!!

我们可以来看一个浏览器的实例:
在这里插入图片描述
其中的https://cn.bing.com/search?q=helloworld,我们可以大致了解其中的原理:

  1. /s应该就是search服务,告诉服务器去执行搜索服务,这个服务不确定是什么语言进行的!
  2. 参数q=helloworld,是使用GET方法传给服务器的!也就是我们要搜索的内容!

通过F12查看页面信息我们也能找到对应的form表单:
在这里插入图片描述
这里的action就是/search

相关文章:

【计网】【计网】从零开始学习http协议 ---理解http重定向和请求方法

去光荣地受伤&#xff0c; 去勇敢地痊愈自己。 --- 简嫃 《水问》--- 从零开始学习http协议 1 知识回顾2 认识网络重定向3 http请求方法3.1 http常见请求方法3.2 postman工具进行请求3.3 处理GET和POST参数 1 知识回顾 前面两篇文章中我们学习并实现了http协议下的请求与应…...

yolov8/9/10/11模型在中医舌苔分类识别中的应用【代码+数据集+python环境+GUI系统】

yolov8、9、10、11模型在中医舌苔分类识别中的应用【代码数据集python环境GUI系统】 背景意义 目前随着人们生活水平的不断提高&#xff0c;对于中医主张的理念越来越认可&#xff0c;对中医的需求也越来越多。 传统中医的舌诊主要依赖于医生的肉眼观察&#xff0c;仅仅通过这…...

k8s部署安装

k8s部署安装 一 K8s集群环境搭建1.1 k8s中容器的管理方式1.2 k8s集群部署1.2.1 k8s环境部署说明1.2.2 k8s集群环境初始化1.2.2.1 所有节点禁用swap和本地解析1.2.2.2 所有节点安装docker1.2.2.3.所有节点设定docker的资源管理模式为systemd1.2.2.4.所有阶段复制harbor仓库中的证…...

gpt为什么可以依据上下文来回答问题,依据的是什么原理

GPT 可以依据上下文回答问题&#xff0c;主要依据以下几个原理&#xff1a; Transformer 架构&#xff1a; 并行计算与长距离依赖处理&#xff1a;Transformer 架构摒弃了传统的递归神经网络和长短时记忆网络的序列依赖处理方式&#xff0c;具有并行计算的能力。它可以同时处理…...

2023 CCPC哈尔滨 报告

比赛链接&#xff1a;Dashboard - 10.6组队训练赛-2023CCPC哈尔滨站 - Codeforceshttps://codeforces.com/group/w6iGs8kreW/contest/552949 做题数&#xff1a;3 题 三题都是队友写的。所以来补一下 B L J。 B题&#xff1a; B. Memory Little G used to be a participant …...

基于深度学习的手术中的增强现实导航

基于深度学习的手术中的增强现实&#xff08;AR&#xff09;导航技术是一种结合了先进的计算机视觉算法、深度学习模型与增强现实技术的创新应用。其主要目的是为外科手术提供实时的、精确的手术指导&#xff0c;帮助医生在复杂的手术过程中更好地理解患者的解剖结构&#xff0…...

输电线路缺陷图像检测数据集,导线散股,塔材锈蚀两类,分别为581张和1407张,标注为xml和txt格式 1988张

输电线路缺陷图像检测数据集&#xff0c;分为导线散股&#xff0c;塔材锈蚀两类&#xff0c;分别为581张和1407张&#xff0c;标注为xml和txt格式 数据集名称 输电线路缺陷图像检测数据集 (Transmission Line Defect Detection Dataset) 数据集概述 该数据集是一个专门用于训…...

百度飞桨(paddlepaddle)安装

百度飞桨&#xff08;paddlepaddle&#xff09;安装 Anaconda升级 打开 Anaconda Prompt &#xff08;或者 Mac 下的终端&#xff09;&#xff0c;键入&#xff1a; conda upgrade --all pip 安装 python -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/s…...

≌图概念凸显有长度不同的射线

黄小宁 【摘要】自有射线概念后的2300年里一直无人能知有长度不同的射线、无人能知有互不≌的射线&#xff0c;从而使数学一直有几何“常识”&#xff1a;任何射线都没有长度差别。保距变换和≌图概念使人能一下子看到有长度不同的射线。 变量x所取各数也均由x代表&#xff0c…...

解决Nginx出现“Too many open files”的问题

解决Nginx出现“Too many open files”的问题 在那个不经意的瞬间&#xff0c;我感到一阵莫名的恍惚。同事突然提出要看我的手机&#xff0c;她的目光落在了我那泛黄的手机壳上。出乎意料地&#xff0c;她开始细心地擦拭&#xff0c;从内到外&#xff0c;动作轻柔而专注。那一刻…...

webGL进阶(一)多重纹理效果

效果&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content&q…...

flink-jdbc-driver

Flink JDBC 驱动程序是一个 Java 库&#xff0c;使客户端能够通过 SQL 网关将 Flink SQL 发送到 Flink 集群。 首先启动&#xff1a;1.flink集群&#xff0c;随意任何集群。 2.启动flink-sql-gateway&#xff1a; sql-gateway.sh start -Dsql-gateway.endpoint.rest.addresslo…...

快速的配置Prettier,让代码更整洁

快速的配置Prettier&#xff0c;让代码更整洁 一个人一个代码风格&#xff0c;先抛开语法的使用不谈&#xff0c;加不加空格、加不加分号也是萝卜白菜各有所爱&#xff0c;那怎么统一我们的代码格式呢 prettier 就是为我们解决这个问题的 1. 如何制定我们的代码风格 我们可以在…...

JavaEE: HTTPS的魅力与优势揭秘

文章目录 HTTPSHTTPS 是什么HTTPS 基本工作过程Fiddle 等抓包工具,为啥能解析 HTTPS 的数据? HTTPS HTTPS 是什么 HTTPS 是一个应用层协议,是在 HTTP 协议的基础上引入了一个加密层. 几个核心概念: 明文: 要传输的原始数据.密文: 把明文进行加密之后得到一个让别人不能理解…...

软件设计师——系统基础开发

&#x1f4d4;个人主页&#x1f4da;&#xff1a;秋邱-CSDN博客☀️专属专栏✨&#xff1a;软考——软件设计师&#x1f3c5;往期回顾&#x1f3c6;&#xff1a;软件设计师——信息安全&#x1f31f;其他专栏&#x1f31f;&#xff1a;C语言_秋邱 ​ 一、软件工程概述 1.1、考…...

架构设计笔记-7-系统架构设计基础知识

目录 知识要点 单选 案例分析 1.质量属性 / 管道过滤器 / 数据仓库风格 2.面向对象风格 / 控制环路风格 3.软件架构风格 / 架构风格选择 4.体系结构方案对比 5.面向对象风格 / 基于规则风格 6.解释器风格 / 管道过滤器风格 7.面向对象风格 / 解释器风格 8.软件架构复…...

跨平台应用程序本地化过程的特点

跨平台应用程序本地化不仅仅是将单词从一种语言翻译成另一种语言。这是关于调整应用程序&#xff0c;使其无缝融入全球用户的不同文化和语言环境&#xff0c;无论他们使用的是哪种设备或平台。这个过程对于跨平台应用程序来说尤其复杂&#xff0c;它们需要在多个操作系统和设备…...

C++面试速通宝典——9

170. 简述数组和指针的区别&#xff1f; ‌‌‌‌  答&#xff1a;数组要么在静态存储区被创建&#xff08;如全局数组&#xff09;&#xff0c;要么在栈上被创建。指针可以随时指向任意类型的内存块。 1. 修改内容上的区别 char a[] “hello”; a[0] ‘X’; char * p …...

阿里巴巴商品详情API返回值:电商行业发展的新动力

阿里巴巴的商品详情API在电商行业中扮演着至关重要的角色&#xff0c;它不仅为商家和消费者提供了丰富的产品信息&#xff0c;还推动了电商行业的进一步发展和创新。通过API接口&#xff0c;开发者可以获取商品的详细信息&#xff0c;如标题、价格、库存、评价等&#xff0c;进…...

php的urlencode和rawurlencode区别

urlencode和rawurlencode都是用于对URL进行编码的函数&#xff0c;但它们在处理方式和应用场景上存在明显的区别。以下是关于这两个函数的详细比较&#xff1a; 一、定义与标准 urlencode&#xff1a;基于rawurlencode标准&#xff0c;但有略微的不同&#xff0c;它定义在rfc…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

使用python进行图像处理—图像滤波(5)

图像滤波是图像处理中最基本和最重要的操作之一。它的目的是在空间域上修改图像的像素值&#xff0c;以达到平滑&#xff08;去噪&#xff09;、锐化、边缘检测等效果。滤波通常通过卷积操作实现。 5.1卷积(Convolution)原理 卷积是滤波的核心。它是一种数学运算&#xff0c;…...

MeanFlow:何凯明新作,单步去噪图像生成新SOTA

1.简介 这篇文章介绍了一种名为MeanFlow的新型生成模型框架&#xff0c;旨在通过单步生成过程高效地将先验分布转换为数据分布。文章的核心创新在于引入了平均速度的概念&#xff0c;这一概念的引入使得模型能够通过单次函数评估完成从先验分布到数据分布的转换&#xff0c;显…...