HTTP3
一、HTTP重定向
1. 概念与原理
- 重定向含义:当浏览器访问一个旧地址时,服务器指示浏览器跳转到新地址,类似于呼叫转移。这在很多场景都会涉及,比如广告点击跳转等 。
- 重定向分类:
- 301 Moved Permanently(永久重定向):表示资源已永久移动到新位置,搜索引擎会更新索引。浏览器会做缓存,下次直接访问新地址,提高效率。
- 302 Move Temporarily(临时重定向):资源临时在新位置,过段时间可能不需要重定向了 。
- 重定向响应:以 302 Found 为例,响应头中会有 Location 字段,指示浏览器接下来要跳转的页面 。如 GET https://c.gdt.qq.com/gdt_click.fcg?viewid=xZFCYGwx88SVZpeyleOC9LYJVCzIcaqTztcFT1ROzXSp5bIV1nFumoJiNj74&s=%7B%22da%22%3A22650%22C%22%22db%22%3A22169%22C%22%22aa%22%3A22218%22C%22%22ab% 请求,服务器响应 HTTP/1.1 302 Found ,并在 Location 字段告知跳转地址。一般3开头的响应不需要body 。
2. 应用场景
- 广告投放:点击广告时,先产生请求访问搜狗的计费服务器(搜狗已被腾讯收购 ),服务器记录点击次数后,通过302响应让浏览器跳转到广告主的服务器,广告主也可统计点击次数 。
二、Cookie
1. 基本概念
- 定义:Cookie本质上是浏览器在本地存储数据的一种机制,以键值对形式存储 。如 Cookie: suid=user_0_D0hFjkFt37rR; pac_uid=0j0hR2kACS4P22; qimei_fingerprint=14b8a37079b0315e3eb1a7 ,使用 ; 分割多个键值对, = 分割键和值 。
- 来源与存储:Cookie中的内容是服务器返回给浏览器的,浏览器保存到本地硬盘。为安全起见,网站只能按“键值对”方式存储简单数据,且后续访问该网站时,Cookie数据会通过HTTP请求头带到服务器 。
- 域名维度管理:浏览器本地存储Cookie时按域名维度进行管理,不同域名下的Cookie相互独立 。
2. 应用场景
- 保存用户身份标识:用户登录时,浏览器发送登录请求(POST ),服务器验证用户名密码后,生成唯一的会话ID(sessionid ),通过 Set - Cookie 响应头返回给浏览器,浏览器将其保存到Cookie中。后续访问同一服务器其他页面时,请求头带上该Cookie,服务器根据sessionid区分用户,避免重复登录 。例如论坛类网站可通过Cookie记录“上次访问时间” 。
- 其他信息存储:还可保存一些不太重要但有用的信息,如流量标签(如 ABTEST=0|1746928954|v17 )用于做实验性的功能 。
3. 与其他存储方式对比
- LocalStorage:也是浏览器本地存储方式,以键值对存储,按域名维度管理,数据不会随HTTP请求自动发送,适合存储不需要频繁传输的数据 。
- IndexDB:类似于数据库,以表结构方式组织数据,适合存储大量结构化数据 。网站相对依赖Cookie存储,而app/桌面程序不太依赖Cookie,可通过访问文件系统进行本地持久化存储 。
三、Referer请求头
1. 定义与作用
- 定义:Referer请求头用于表示页面是从哪里来的,不是所有请求都有该字段 。例如在页面跳转时,会带上Referer ,如 GET https://www.sogou.com/web?query=%E8%9B%8B%E8%82%9D%E7%B3%95&Referer: https://www.sogou.com/ 。
- 作用:主要给服务器看,用于广告平台统计流量来源等。比如广告主可通过Referer判断访问来源是搜狗还是百度等 。
2. 相关问题与技术应对
- 无效点击与反作弊:广告投放中存在无效点击(用户去广告主消费但无实际价值 ),广告平台(如搜狗 )有反作弊算法识别无效点击,有效点击计费,无效点击不计费 。
- Referer篡改问题:存在运营商篡改Referer的情况,将广告请求的Referer改成其他广告平台的,以抢夺流量。广告平台如搜狗、百度等通过法律(起诉运营商 )和技术(推进HTTPS,在HTTP基础上引入加密层,防止数据被篡改 )手段应对 。
四、HTTP状态码
1. 常见状态码含义
- 200 OK:表示访问成功,但只是HTTP层面成功,不代表业务层面成功。例如注册账号时,提交用户名后因用户名重复注册失败,虽服务器返回200状态码,但业务上是失败的。业务层面的成功失败通常在body的json中用专门的 code / ok / success 等属性标识 。
- 404 Not Found:表示请求的资源不存在,如搜狗的404页面较原始,很多网站会设计美观的404页面 。
- 403 Forbidden:表示访问被拒绝,用户没有权限访问,权限问题与业务相关 。
- 500 Internal Server Error:常见的服务器错误,代码抛出异常未被很好捕获时出现,知名网站对稳定性要求高,一年不可用时间不能超过5分钟 。
- 502 Bad Gateway:网关错误,服务器机房入口服务出现问题 。
- 504 Gateway Timeout:网关超时,网关本身较稳定,但后面连接的机器挂掉会导致此错误 。
- 特殊状态码:如418 I am a teapot,写入HTTP标准协议但没啥实际用,是个有趣的彩蛋 。
2. 状态码应用场景
- 开发与权限控制:开发时,涉及权限控制场景,可通过 403 返回给客户端表示无权限;也可返回 200 ,在body中用业务标识表示无权限 。
五、代码示例(以Java为例)
1. 模拟带Cookie的请求
import java.io.IOException;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.HttpCookie;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class CookieExample {
public static void main(String[] args) throws IOException, InterruptedException {
// 设置Cookie管理器
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
HttpClient client = HttpClient.newBuilder()
.cookieHandler(cookieManager)
.build();
// 模拟登录获取Cookie
String loginUrl = "https://example.com/login";
HttpRequest loginRequest = HttpRequest.newBuilder()
.uri(URI.create(loginUrl))
.POST(HttpRequest.BodyPublishers.ofString("username=your_username&password=your_password"))
.build();
HttpResponse<String> loginResponse = client.send(loginRequest, HttpResponse.BodyHandlers.ofString());
// 获取响应中的Cookie
for (HttpCookie cookie : cookieManager.getCookieStore().getCookies()) {
System.out.println(cookie);
}
// 使用Cookie访问其他页面
String targetUrl = "https://example.com/some_page";
HttpRequest targetRequest = HttpRequest.newBuilder()
.uri(URI.create(targetUrl))
.GET()
.build();
HttpResponse<String> targetResponse = client.send(targetRequest, HttpResponse.BodyHandlers.ofString());
System.out.println(targetResponse.body());
}
}
2. 处理重定向请求
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class StatusCodeExample {
public static void main(String[] args) throws IOException, InterruptedException {
HttpClient client = HttpClient.newHttpClient();
String url = "https://example.com";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
int statusCode = response.statusCode();
switch (statusCode) {
case 200:
System.out.println("访问成功");
break;
case 404:
System.out.println("页面未找到");
break;
case 500:
System.out.println("服务器内部错误");
break;
default:
System.out.println("其他状态码: " + statusCode);
}
}
}