HTTP/HTTPS 学习笔记(中):报头、Cookie、状态码与请求构造
本文是 HTTP/HTTPS 系列博客的中篇,重点整理 HTTP 报头、Cookie 登录、请求正文格式、响应状态码以及如何构造 HTTP 请求。
一、认识请求报头 Header
请求报头的基本格式是键值对:
http
Host: www.sogou.com
Connection: keep-alive
Content-Length: 105
Content-Type: application/json;charset=UTF-8
User-Agent: Mozilla/5.0 ...
Referer: https://v.bitedu.vip/login
Cookie: username=123456789; rememberMe=true
常见字段:
Host:服务器地址;Connection:连接方式,如 keep-alive;Content-Length:Body 长度;Content-Type:Body 数据格式;User-Agent:浏览器/操作系统属性;Referer:页面从哪个页面跳转过来;Cookie:身份标识信息。
Content-Type 常见类型
application/x-www-form-urlencoded:表单提交;multipart/form-data:文件上传;application/json:JSON 数据。
User-Agent
User-Agent 简称 UA,表示浏览器和操作系统信息。例如:
text
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ...
其中包含操作系统、浏览器内核等信息。UA 的格式之所以奇怪,是历史遗留问题。
Referer
Referer 表示这个页面是从哪个页面跳转过来的。如果直接在浏览器输入 URL,或者通过收藏夹访问,通常没有 Referer。
二、Cookie 与登录
Cookie 中存储了一个字符串,可能由客户端 JS 写入,也可能来自服务器。服务器可以在 HTTP 响应中通过 Set-Cookie 字段给浏览器返回数据。
Cookie 常用于实现"身份标识"。每个域名下都可以有不同的 Cookie,不同网站之间的 Cookie 并不冲突。
以码云登录为例:
- 先清除之前的 Cookie;
- 输入用户名密码,点击登录;
- 登录请求发送到服务器;
- 服务器返回 302,并在响应头中
Set-Cookie; - 其中
gitee-session-n就是用户当前登录的身份标识,也称为"令牌"; - 后续访问其他页面时,请求中都会带着这个 Cookie。
这个过程和去医院看病很像:
- 先挂号,提供身份证,得到就诊卡;
- 后续去各科室,不必再出示身份证,凭就诊卡识别身份;
- 看完病可以注销就诊卡;
- 再次看病可以办新卡,得到新令牌。
三、认识请求正文 Body
Body 的格式与 Content-Type 密切相关。
1. application/x-www-form-urlencoded
例如上传头像:
http
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
avatar=data%3Aimage%2Fpng%3Bbase64%2C...
数据会被 URL encode。
2. multipart/form-data
用于文件上传:
http
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary...
------WebKitFormBoundary...
Content-Disposition: form-data; name="file"; filename="简历.pdf"
Content-Type: application/pdf
%PDF-1.7 ...
3. application/json
例如登录:
http
Content-Type: application/json; charset=UTF-8
{"username":"123456789","password":"xxxx","code":"jw7l","uuid":"..."}
网络传输中带宽稀缺,数据常被压缩。Fiddler 可以解压缩查看原始内容。
四、HTTP 响应状态码
状态码分为五大类:
| 类别 | 含义 |
|---|---|
| 1XX | Informational,信息性状态码,接收的请求正在处理 |
| 2XX | Success,成功状态码,请求正常处理完毕 |
| 3XX | Redirection,重定向状态码,需要附加操作 |
| 4XX | Client Error,客户端错误,服务器无法处理请求 |
| 5XX | Server Error,服务器错误,服务器处理请求出错 |
常见状态码:
404 Not Found
没有找到资源。访问的 URL 对应资源不存在。
403 Forbidden
访问被拒绝。通常需要登录或权限才能访问。
405 Method Not Allowed
服务器不支持请求方法,或不允许使用该方法。
500 Internal Server Error
服务器内部错误,通常是服务器代码执行异常。
504 Gateway Timeout
服务器负载大,处理请求超时。双十一"秒杀"场景容易出现。
302 Move temporarily
临时重定向。类似手机"呼叫转移"。登录成功后自动跳转主页常用 302。
响应头中会包含:
http
Location: https://gitee.com/HGtz2222
浏览器收到后会自动发送新的 GET 请求。
301 Moved Permanently
永久重定向。浏览器后续请求会自动改成新地址。
五、响应报头与正文
响应报头格式和请求报头基本一致。常见响应 Content-Type:
text/html:HTML;text/css:CSS;application/javascript:JavaScript;application/json:JSON。
响应正文格式取决于 Content-Type。例如 HTML 页面、CSS 文件、JS 文件、JSON 数据等。
六、构造 HTTP 请求
1. 通过 form 表单构造
html
<form action="http://abcdef.com/myPath" method="GET">
<input type="text" name="userId">
<input type="text" name="classId">
<input type="submit" value="提交">
</form>
对应关系:
action:HTTP 请求 URL;method:GET 或 POST;input name:query string 的 key;input value:query string 的 value。
GET 请求会把数据放到 URL:
http
GET http://abcdef.com/myPath?userId=100&classId=200 HTTP/1.1
POST 请求会把数据放到 Body:
http
POST http://abcdef.com/myPath HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
userId=100&classId=200
2. 通过 ajax 构造
js
$.ajax({
type: 'get',
url: 'https://www.sogou.com?studentName=zhangsan',
success: function(data) {
console.log(data);
}
});
POST 示例:
js
$.ajax({
type: 'post',
url: 'https://www.sogou.com',
contentType: 'application/json',
data: '{name: "zhangsan"}',
success: function(data) {
console.log(data);
}
});
ajax 默认不能跨域。跨域需要服务器配合,在响应中允许跨域。
3. 通过 Java Socket 构造
本质上,发送 HTTP 请求就是往 TCP Socket 写入符合 HTTP 格式的字符串;接受响应就是读取字符串并解析。
java
public String get(String url) throws IOException {
StringBuilder request = new StringBuilder();
request.append("GET " + url + " HTTP/1.1\n");
request.append("Host: " + ip + ":" + port + "\n");
request.append("\n");
outputStream.write(request.toString().getBytes());
// 读取响应...
}
使用 Java 构造 HTTP 客户端没有浏览器"跨域"限制,可以获取其他服务器数据。跨域只是浏览器对 ajax 的行为。