文章目录
HTTP (全称为 “超文本传输协议”) 是一种应用非常广泛的应用层协议。
1.基于某个特定的传输层协议(TCP)之上
2.描述业务
3.非OS系统
当我们在浏览器中输入一个 “网址”, 此时浏览器就会给对应的服务器发送一个 HTTP 请求. 对方服务器收到这个请求之后, 经过计算处理, 就会返回一个 HTTP 响应。

事实上, 当我们访问一个网站的时候, 可能涉及不止一次的 HTTP 请求/响应 的交互过程。

注意: 为什么 HTTP 报文中要存在空行呢?
- 因为 HTTP 协议并没有规定报头部分的键值对有多少个,使用空行就相当于是报文的结束标记或报文和正文之间的分隔符
- HTTP 在传输层依赖 TCP 协议,TCP 是面向字节流的。如果没有这个空行,就会出现”粘包问题“

URL (Uniform Resource Locator 统一资源定位符),互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。

URL的具体格式:
域名 (domain) 或者ip来体现一主机 (host)端口 (port)路径 (path)protocol / schema)查询字符串 query string、文档片段 fragment)| 方法 | 说明 | 适用版本号 |
|---|---|---|
| GET | 获取资源 | HTTP 1.0、HTTP 1.1 |
| POST | 传输实体主体 | HTTP 1.0、HTTP 1.1 |
| PUT | 传输文件 | HTTP 1.0、HTTP 1.1 |
| HEAD | 获得报文首部 | HTTP 1.0、HTTP 1.1 |
| DELETE | 删除文件 | HTTP 1.0、HTTP 1.1 |
| OPTIONS | 访问支持的方法 | HTTP 1.1 |
| TRACE | 追踪路径 | HTTP 1.1 |
| CONNECT | 要求用隧道协议连接代理 | HTTP 1.1 |
| LINK | 建立和资源之间的联系 | HTTP 1.1 |
| UNLINE | 断开连接关系 | HTTP 1.1 |
GET 是最常用的 HTTP 方法,常用于获取服务器上的某个资源。
GET 请求的特点:
%E8%9B%8B%E7%B3%95GET 请求示例: 搜狗首页请求

POST 方法也是一种常见的方法,多用于提交用户输入的数据给服务器(如登录页面)。
POST 请求的特点:
POST 请求示例: QQ 邮箱登录请求

回到目录…
我们平时构建发送的 GET/POST请求:
| 请求方法 | 构建方式 |
|---|---|
| GET | 1.地址栏输入url回车 2. 通过一些标签 <img>;、<script>、<link>3.还有一些标签 <a>、<form> 4. ajax 5. 重定向(redirect) |
| POST | 1. <form method="post"> 2. ajax 3. 重定向(redirect) |
面试题:GET 和 POST 的区别
GET 和 POST 其实没有本质区别,使用 GET 的场景完全可以使用 POST 代替,使用 POST 的场景一样可以使用 GET 代替。但是在具体的使用上,还是存在一些细节的区别
GET 习惯上会把客户端的数据通过 query string 来传输(body 部分是空的);POST 习惯上会把客户端的数据通过 body 来传输(query string 部分是空的)
GET 习惯上用于从服务器获取数据;POST 习惯上是客户端给服务器提交数据
一般情况,程序员会把 GET 请求的处理,实现成“幂等”的;对于 POST 请求的处理,不要求实现成“幂等”
GET 请求可以被缓存,可以被浏览器保存到收藏夹中;POST 请求不能被缓存
header 的整体格式是键值对结构,每个键值对占一行,键和值之间使用 冒号+空格 进行分割
| key | value |
|---|---|
| Host | 表示服务器主机的地址和端口 |
| Content-Length | 表示 body 的数据长度,长度单位是字节 |
| Content-Type | 表示 body 的数据格式 |
| User-Agent | 表示浏览器或者操作系统的属性 |
| Referer | 表示这个页面是从哪个页面跳转过来的 |
| Cookie | 是浏览器提供的一种让程序员在本地存储数据的能力 |
Content-Type 有以下三种请求中的数据格式:
application/x-www-form-urlencoded这是 form 表单提交的数据格式,此时 body 的格式就类似于 query string(是键值对的结构,键值对之间使用 & 分割,键与值之间使用 = 分割
multipart/form-data这是 form 表单提交的数据格式(需要在 from 标签上加上
enctyped="multipart/form-data"),通常用于 HTML 提交图片或者文件
application/json此时 body 数据为 json 格式,json 格式就是源自 js 的对象的格式。用一个 { } 括住,里面有多个键值对,键值对之间使用逗号分割,键和值之间使用冒号分割

常见的状态码
| 常见状态码 | 说明 |
|---|---|
| 200 OK | 这是一个最常见的状态码, 表示访问成功。抓包抓到的大部分结果都是 200 |
| 404 Not Found | 没有找到资源。URL 标识的资源不存在, 那么就会出现 404 |
| 403 Forbidden | 表示访问被拒绝。有的页面通常需要用户具有一定的权限才能访问(登陆后才能访问).。如果用户没有登陆直接访问, 就容易见到 403 |
| 405 Method Not Allowed | 我们学习了 HTTP 中所支持的方法, 有 GET, POST, PUT, DELETE 等。但是对方的服务器不一定都支持所有的方法(或者不允许用户使用一些其他的方法). |
| 500 Internal Server Error | 服务器出现内部错误. 一般是服务器的代码执行过程中遇到了一些特殊情况(服务器异常崩溃)会产生这个状态码,一般很少见 |
| 504 Gateway Timeout | 当服务器负载比较大的时候, 服务器处理单条请求的时候消耗的时间就会很长, 就可能会导致出现超时的情况 |
| 302 Move temporarily | 临时重定向。在登陆页面中经常会见到 302. 用于实现登陆成功后自动跳转到主页 |
| 301 Moved Permanently | 永久重定向。当浏览器收到这种响应时, 后续的请求都会被自动改成新的地址。301 也是通过 Location 字段来表示要重定向到的新地址 |
总结
| 类别 | 原因短语 | |
|---|---|---|
| 1XX | Informational (信息性状态码) | 接受的请求正在处理 |
| 2XX | Success (成功状态码) | 请求正常处理完毕 |
| 3XX | Redirection (重定向状态码) | 需要进行附加操作以完成请求 |
| 4XX | Client Error (客户端错误状态码) | 服务器无法处理请求 |
| 5XX | Server Error (服务器错误状态码) | 服务器处理请求出错 |
响应报头的基本格式和请求报头的格式基本一致。
下面介绍下响应报头的 Content-Type 参数
text/html表示数据格式是 HTML
text/css表示数据格式是 CSS
application/javascript表示数据各式是 JavaScript
application/json表示数据格式是 JSON
import java.io.*;
import java.net.Socket;
// HTTP 客户端
public class HTTPClient {
public static void main(String[] args) throws IOException {
// 1. HTTP 客户端,要发送 HTTP 请求,先建立 TCP 连接
// 我们当前进程和www.baidu.com主机上绑定 8080 端口的进程使用 TCP 通信(要求 建立 TCP 连接)
Socket socket = new Socket("localhost", 80);
OutputStream os = socket.getOutputStream();
PrintWriter writer = new PrintWriter(new OutputStreamWriter(os, "UTF-8"));
// 只有请求行,请求头为空,没有请求体
String request = "GET / HTTP/1.0\r\n\r\n";
writer.print(request);
// 冲刷缓冲区
writer.flush();
// 读取百度返回的 HTTP 响应
InputStream is = socket.getInputStream();
byte[] buf = new byte[10240]; // 我们知道响应不会超过 1024 字节的
int n = is.read(buf);
String response = new String(buf, 0, n, "UTF-8");
System.out.println(response);
}
}
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
// HTTP 服务端
public class HTTPServer {
public static void main(String[] args) throws IOException {
// 我们使用短连接
ServerSocket serverSocket = new ServerSocket(80);
while (true) {
try {
Socket socket = serverSocket.accept();
// 不管对方发给我们的 请求 是什么,一律使用统一的响应回复对方
OutputStream os = socket.getOutputStream();
PrintWriter writer = new PrintWriter(new OutputStreamWriter(os, "UTF-8"));
String html = "<a href='https://www.baidu.com/'>百度一下</a>"; // 我们的响应体
byte[] bytes = html.getBytes("UTF-8");
int contentLength = bytes.length;
String response = "HTTP/1.0 200 OK\r\n" +
"Content-Type: application/octet-stream; charset=utf-8\r\n" +
"Content-Length: 49\r\n" +
"\r\n" +
html;
writer.print(response);
writer.flush();
socket.close();
} catch (IOException exc) {
exc.printStackTrace();
}
}
}
}
总结:
提示:这里对文章进行总结:
以上就是今天的学习内容,本文是HTTP协议的学习,了解HTTP协议的工作过程,HTTP的请求和响应格式,以及如何手写HTTP服务器。之后的学习内容将持续更新!!!
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba
我正在使用Heroku(heroku.com)来部署我的Rails应用程序,并且正在构建一个iPhone客户端来与之交互。我的目的是将手机的唯一设备标识符作为HTTPheader传递给应用程序以进行身份验证。当我在本地测试时,我的header通过得很好,但在Heroku上它似乎去掉了我的自定义header。我用ruby脚本验证:url=URI.parse('http://#{myapp}.heroku.com/')#url=URI.parse('http://localhost:3000/')req=Net::HTTP::Post.new(url.path)#boguspara
我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token
我是Ruby的新手。我试过查看在线文档,但没有找到任何有效的方法。我想在以下HTTP请求botget_response()和get()中包含一个用户代理。有人可以指出我正确的方向吗?#PreliminarycheckthatProggitisupcheck=Net::HTTP.get_response(URI.parse(proggit_url))ifcheck.code!="200"puts"ErrorcontactingProggit"returnend#Attempttogetthejsonresponse=Net::HTTP.get(URI.parse(proggit_url)
我正在尝试解析网页,但有时会收到404错误。这是我用来获取网页的代码:result=Net::HTTP::getURI.parse(URI.escape(url))如何测试result是否为404错误代码? 最佳答案 像这样重写你的代码:uri=URI.parse(url)result=Net::HTTP.start(uri.host,uri.port){|http|http.get(uri.path)}putsresult.codeputsresult.body这将打印状态码和正文。
我正在安装gitlabhq,并且在Gemfile中有对某些资源的“git://...”的引用。但是,我在公司防火墙后面,所以我必须使用http://。我可以手动编辑Gemfile,但我想知道是否有另一种方法告诉bundler使用http://作为git存储库? 最佳答案 您可以通过运行gitconfig--globalurl."https://".insteadOfgit://或通过将以下内容添加到~/.gitconfig:[url"https://"]insteadOf=git://