HTTP 的工作原理是什么?
以下是HTTP请求/响应的步骤:
客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。释放连接TCP连接
Web服务器主动关闭TCP套接字,释放TCP连接;客户端被动关闭TCP套接字,释放TCP连接。客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
HTTP 状态码知道哪些?
301 和 302 的区别是什么?
态代码 | 状态信息 | 含义 |
---|---|---|
200 | OK | 一切正常,对GET和POST请求的应答文档跟在后面。 |
301 | Moved Permanently | 客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL。(永久重定向,浏览器会记住) |
302 | Moved Temporary | 临时重定向 |
304 | Not Modified | 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告 诉客户,原来缓冲的文档还可以继续使用。 |
403 | Forbidden | 资源不可用。服务器理解客户的请求,但拒绝处理它。通常由于服务器上文件或目录的权限设置导致。 |
404 | Not Found | 无法找到指定位置的资源。这也是一个常用的应答。 |
500 | Internal Server Error | 服务器遇到了意料不到的情况,不能完成客户的请求。 |
503 | Service Unavailable | 服务器由于维护或者负载过重未能应答。例如,Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个 Retry-After头。 |
HTTP 缓存怎么做?
- Cache-Control: max-age=300 (不发请求,0.3秒后过期)
- Last-Modified
- Etag (发请求,但不下载)
- Expires(HTTP1.0产物,用GMT时间,若用户本地时间错乱,则会缓存出错,不发请求 )
浏览器总是优先使用cache-control,如果没有cache-control才考虑Expires
Cache-Control 和 Etag 的区别是什么?
1. Cache-Control
Cache-Control 在 HTTP 响应头中,用于指示代理和 UA 使用何种缓存策略
策略 | 目的 |
---|---|
no-cache | 为本次响应不可直接用于后续请求(在没有向服务器进行校验的情况下) |
no-store | 为禁止缓存(不得存储到非易失性介质,如果有的话尽量移除,用于敏感信息) |
private | 为仅 UA 可缓存 |
public | 为大家都可以缓存。 |
当Cache-Control为可缓存时,同时可指定缓存时间(比如public, max-age:86400)。 这意味着在 1 天(60x60x24=86400)时间内,浏览器都可以直接使用该缓存(此时服务器收不到任何请求)。 当然浏览器也有权随时丢弃任何一项缓存,因此这里可能有一致性问题。
2. Etag
ETag
ETag是实体标签(Entity Tag)的缩写, 根据实体内容生成的一段hash字符串(类似于MD5或者SHA1之后的结果),可以标识资源的状态。 当资源发送改变时,ETag也随之发生变化。
ETag是Web服务端产生的,然后发给浏览器客户端。浏览器客户端是不用关心Etag是如何产生的。
在请求里ETag的数据会放在If-None-Match里面,当下次请求是查看ETag和If-None-Match的值是否相同,若相同,则返回status为304,不下载响应体
为什么使用ETag呢? 主要是为了解决Last-Modified 无法解决的一些问题。
某些服务器不能精确得到文件的最后修改时间, 这样就无法通过最后修改时间来判断文件是否更新了。
某些文件的修改非常频繁,在秒以下的时间内进行修改. Last-Modified只能精确到秒。
一些文件的最后修改时间改变了,但是内容并未改变。 我们不希望客户端认为这个文件修改了。
Http报文
报文有哪几部分组成?
- 请求报文的组成(request)
- 起始行(请求方法,URI及协议版本)
- 首部(请求首部, 通用首部 ,实体首部及其他)
- 空行
- 报文主体;
- 响应报文的组成(reponse)
- 起始行(版本协议 ,状态码, 状态码对应的短语解释)
- 首部(响应首部,通用首部,实体首部及其他)
- 空行
- 报文主体。
HTTP/1.0 200 OK
content-type: text/plain
content-length: 19
Hi, I'm a message
Request头部 | 含义 |
---|---|
Cache-Control: max-age=0 | 以秒为单位 |
If-Modified-Since: Mon, 19 Nov 2012 08:38:01 GMT | 缓存文件的最后修改时间。 |
If-None-Match: "0693f67a67cc1:0" | 缓存文件的Etag值 |
Cache-Control: no-cache | 不使用缓存 |
Pragma: no-cache | 不使用缓存 |
Response头部 | 含义 |
---|---|
Cache-Control: public | 响应被缓存,并且在多用户间共享, (公有缓存和私有缓存的区别,请看另一节) |
Cache-Control: private | 响应只能作为私有缓存,不能在用户之间共享 |
Cache-Control:no-cache | 提醒浏览器要从服务器提取文档进行验证 |
Cache-Control:no-store | 绝对禁止缓存(用于机密,敏感文件) |
Cache-Control: max-age=60 | 60秒之后缓存过期(相对时间) |
Date: Mon, 19 Nov 2012 08:39:00 GMT | 当前response发送的时间 |
Expires: Mon, 19 Nov 2012 08:40:01 GMT | 缓存过期的时间(绝对时间) |
Last-Modified: Mon, 19 Nov 2012 08:38:01 GMT | 服务器端文件的最后修改时间 |
ETag: "20b1add7ec1cd1:0" | 服务器端文件的Etag值 |
Cookie 是什么?Session 是什么?
一般情况下,session是基于cookie实现的。
Cookie 的特点
前三个为cookie的说明
- 服务器通过 Set-Cookie 响应头设置 Cookie
- 浏览器得到 Cookie 之后,每次请求都要带上Cookie 作为 Request Header
- 服务器读取 Cookie 就知道登录用户的信息(如email)
- 一般用来记录用户信息
- Cookie存在C盘的某一文件
- Cookie可以修改(所以不太安全)
- 默认用户关闭页面后就失效,但后台可以设置Cookie的过期时间
Session
服务器通过Cookie给用户一个SessionID,Session是服务器的一小块内存,用户访问服务器的时候,服务器通过SessionID读取用户的隐私信息
- 将 SessionID(随机数)通过 Cookie 发给客户端
- 客户端访问服务器时,服务器读取 SessionID
- 服务器有一块内存(哈希表)保存了所有 session
- 通过 SessionID 我们可以得到对应用户的隐私信息,如 id、email
- 这块内存(哈希表)就是服务器上的所有 session
- Session 一般通过在 Cookie 里记录 SessionID 实现
LocalStorage 和 Cookie 的区别是什么?
区别:
- Cookie 会随请求被发到服务器上,而 LocalStorage 不会
- Cookie 大小一般4k以下,LocalStorage 一般5Mb 左右
LocalStorage
- LocalStorage是HTML5提供的一个新的api
- LocalStorage与HTTP无关
- HTTP不会带上LocalStorage的值
- 只有相同域名的页面才能互相读取LocalStorage
- 每个域名的LocalStorage最大存储量为5Mb左右(每个浏览器不一样)
- 常用场所:记录没什么用的信息
- LocalStorage理论上不会过期,除非清理缓存
SessionStorage(回话存储)
2,3,4,5同LocalStorage
与Session一点关系都没有
LocalStorage与SessionStorage区别:关闭页面(回话结束)后就失效
GET 和 POST 的区别是什么?(必考)
- 参数。GET 的参数放在 url 的查询参数里,POST 的参数(数据)放在请求消息体里。
- 安全(扯淡)。GET 没有 POST 安全(都不安全)
GET 的参数(url查询参数)有长度限制,一般是 1024 个字符。POST 的参数(数据)没有长度限制(扯淡,4~10Mb 限制)
包。GET 请求只需要发一个包,POST 请求需要发两个以上包(因为 POST 有消息体)(扯淡,GET 也可以用消息体)
GET 用来读数据,POST 用来写数据,POST 不幂等(幂等的意思就是不管发多少次请求,结果都一样。)
怎么跨域?JSONP 是什么?CORS 是什么?postMessage 是什么?(必考)
JSONP
CORS
postMessage 看一下 MDN