Skip to content

前端天罗地网

网络

TCP

三次握手(创建连接)

客户端向服务端发起连接请求,一个带有SYN(sychronize)标志与连接序列号x的数据包

服务端收到连接请求,回复ACK确认号x+1确认收到,并携带SYN表示同意连接请求,y作为连接序列号

客户端收到SYN+ACK+y数据包,再回复ACK确认号y+1,连接建立

四次挥手(关闭连接)

客户端向服务端发起关闭信号FIN(finish),即不再发送请求但可以接收请求

服务端收到关闭请求,回复确认号ACK,此时还可继续发送请求

服务端不再需要发送请求后,发送关闭信号FIN

客户端收到服务端关闭信号,回复ACK确认号,关闭连接

HTTP

Content-type

前端对发起的请求所携带的请求体的格式声明,告知后端如何处理接收到的数据:

  • application/json json格式
  • application/x-www-form-urlencoded

常用于简单文本表单提交,以url编码(序列化)的格式放在post请求的请求体中,并不是get请求那般拼接url

  • multipart/form-data;boundary=----随机字符串

常用于复杂的携带文件的表单提交,表单数据以boundary分隔符隔开,boundary由请求库自动生成也可以自定义

JavaScript
POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

----WebKitFormBoundary7MA4YWxkTrZu0gW // 必须以--开头
Content-Disposition: form-data; name="username"

John
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain

(文件内容)
----WebKitFormBoundary7MA4YWxkTrZu0gW-- // 结尾加--表示表单的末尾
  • text/plain 纯文本
  • text/html html文档
Data-type

前端在请求库中设置(例如ajax的dataType属性),告知后端,前端希望收到什么类型的响应数据

  • json: 期望服务器返回JSON格式的数据。
  • xml: 期望服务器返回XML格式的数据。
  • text: 期望服务器返回纯文本数据。
  • html: 期望服务器返回HTML文档。
状态码
Https
Http2.0
SSL

网页

解析流程

SEO

安全

XSS(Cross-Site Scripting)

CSRF(Cross-Site Request Forgery)

缓存

为解决Http不带有状态的问题,服务器在客户端保留的少量状态数据,一般不超过4KB。

Cookie包含cookie名,值,到期时间ExpireMax-Age ,所属域名 Domain ,生效路径Path

服务端

通过响应请求设置Set-Cookie字段配置cookie,一个Set-Cookie只能设置一个cookie键值对,可以使用多个Set-Cookie设置多个cookie。

客户端

通过document.cookie设置Cookie的内容,发送请求时添加请求头Cookie字段发送cookie。

设置 window.navigator.**cookieEnable **为false则禁用了cookie的读取和写入,可以让请求不接收也不发送cookie。

属性

Expire :绝对时间,过期时间点。

Max-Age :相对时间,多长时间后过期。

Domain :默认cookie只在当前域和子域名有效,domain前端 只能设为自身或上级域名 ,其中上级域名也不能是公共域名(github.io)或顶级域名(.top/.com),设置之后在自身与子域名间生效。

Path :cookie在 当前路径及子路径范围内生效 ,只有路径匹配时才发送携带Cookie的请求到服务器

HttpOnly :只有发起HTTP请求可以带cookie,无法通过JS访问document.cookie,防止XSS(Cross-Site Scripting)攻击。 只有后端可设置 ,前端如果设置HttpOnly则不能通过js访问cookie,这与该配置悖论。

Secure :只有发起https请求才能携带cookie,页面可以为http。如果前端设置该字段需页面也为HTTPS才可设置。

SameSite :限制跨站http请求中cookie的发送,防止CSRF(Cross-Site Request Forgery)攻击:

strict完全禁止跨站cookie;

Lax允许部分跨站请求,如子域名共享,如导航跳转url的GET请求(location.href、a标签),<form method='GET'>等;(Chrome、FireFox默认值)

None完全允许跨站请求携带cookie(必须Secure,所以也限制了前端页面必须HTTPS)。

document.cookie可以获取当前网站所有的cookie,但设置cookie只能和服务端一样,一次设置一个

JavaScript
document.cookie = 'test1=hello';
document.cookie = 'test2=world';
document.cookie // test1=hello;test2=world

cookie设置完便不可读取属性,只能通过设置过期时间来删除cookie

JavaScript
// 删除fontSize属性
document.cookie = 'fontSize=;expires=Thu, 01-Jan-1970 00:00:01 GMT';

答疑

为什么有domain还需要sameSite?

domain与path只限制了cookie作用域,无法限制跨站请求,即跨站网站虽无法获取cookie,但跨站的link/script/img标签,xhr,表单请求等,仍可携带cookie,这是浏览器兼容的遗留问题,所以这就需要sameSite来保证安全了。

cookie能不能跨域?
cookie访问权限

总结:配置可支持同站跨域;无法通过配置实现跨站,需借助其他方式。

  • 同站跨域:配置实现
    • window.navigator.cookieEnable = true(默认);
    • domain="父级域名",子域名间可以共享;
    • path="/",或其他路径,总之保证包含你想共享cookie的子路径;
  • 跨站:借助其他方式实现
    • window.navigator.cookieEnable = true(默认);
    • 通过postmessage发送document.cookie,或其他跨域请求的方案
请求携带cookie

总结:同站跨域默认支持部分;配置支持跨站。

  • 同站跨域(子域名之间)
    • 同站跨域的cookie访问权限
    • sameSite配置:
      • sameSite="Lax"(默认),支持导航跳转url请求和Form Get表单提交,不需要CORS配置;
      • sameSite="None",同时Secure=true,支持所有请求,后端必须配置CORS;
    • 请求库配置withCredentials = true 允许请求携带cookie
  • 跨站
    • window.navigator.cookieEnable = true(默认);
    • sameSite="None",同时Secure=true;
    • 请求库配置withCredentials = true
    • 配置CORS(Access-Control-Allow-OriginAccess-Control-Allow-Credentials);

强缓存

浏览器直接从本地缓存中读取资源,不发送请求到服务器。

Cache-Control

  • max-age=<seconds>: 缓存最大有效时间(秒)。
  • no-cache: 协商缓存 ,向服务器验证缓存是否过期,如果服务返回304 Not Modified,前端则使用缓存。
  • no-store: 不缓存任何内容。
  • public: 允许所有用户缓存资源,即共享缓存,可以被浏览器、CDN、代理服务器缓存。
  • private: 仅允许单个用户缓存资源,即只能被浏览器缓存。
  • immutable:表示资源永远不会变,无需验证直接使用缓存。

Expires

指定资源的过期时间(HTTP/1.0 的字段,逐渐被 Cache-Control 取代)。

HTTP
Cache-Control: max-age=3600, public
Expires: Wed, 01 Jan 2025 00:00:00 GMT

html文件上如果通过meta标签配置了缓存策略则会优先以html文件的配置为准

HTML
<meta http-equiv="Cache-Control">

协商缓存

浏览器向服务器发送请求,验证本地缓存是否仍然有效。

Last-Modified If-Modified-Since

  • 资源最后的修改时间(Last-Modified),由服务器返回。
  • 浏览器下次请求时带上 If-Modified-Since,服务器据此判断资源是否更新。

ETagIf-None-Match :

  • 服务器返回资源的唯一标识(ETag)。
  • 浏览器下次请求时带上 If-None-Match,服务器根据标识判断资源是否更新。
HTTP
Last-Modified: Wed, 01 Jan 2020 00:00:00 GMT
ETag: "abc123"

Session

Token JWT

请求

同源策略

如果非同源,共有三种行为受到限制。

(1) 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB。

(2) 无法接触非同源网页的 DOM。

(3) 无法向非同源地址发送 AJAX 请求(可以发送,但浏览器会拒绝接受响应)。

跨域方案

CORS

CORS 是一个 W3C 标准,全称是“跨源资源共享”(Cross-origin resource sharing),或者通俗地称为“跨域资源共享”。它允许浏览器跨源发出 XMLHttpRequest请求,克服了 AJAX 只能同源使用的限制。

简单请求
简单请求的判定

(1)请求方法是以下三种方法之一。

  • HEAD
  • GET
  • POST

(2)HTTP 的头信息不超出以下几种字段。

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值 application/x-www-form-urlencodedmultipart/form-datatext/plain
简单请求的流程

简单请求直接发起CORS请求,请求头自动增加Origin字段。

如果Origin不在服务器跨域许可范围,则返回正常的HTTP回应,浏览器发现没有Access-Control-Allow-Origin则会抛出错误,此时状态码可能仍然是200。

正确的Origin则会得到服务器新增的三个header:

(1) Access-Control-Allow-Origin

该字段是必须的。它的值要么是请求时 Origin字段的值,要么是一个 *

(2) Access-Control-Allow-Credentials

是否允许发送 Cookie,默认Cookie 不包括在 CORS 请求之中。同时也需要配置 xhr.withCredentials=true ,且Access-Control-Allow-Origin不能是*,因为cookie必须是同源的

(3) Access-Control-Expose-Headers

CORS 请求时,XMLHttpRequest对象的 getResponseHeader()方法只能拿到6个服务器返回的基本字段:Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma。如果想拿到其他字段,就必须在 Access-Control-Expose-Headers里面指定 Access-Control-Expose-Headers:字段名

非简单请求

JSONP

原理源码

利用 <script>标签不受同源策略限制的特点,通过动态创建script标签,将GET请求当作脚本src发起,并让其携带回调函数,服务器把数据拼接到回调函数里返回,例如 foo(123),浏览器会当作script标签返回的脚本,进行代码解析后并执行

JavaScript
function addScriptTag(src) {
  var script = document.createElement('script');
  script.setAttribute('type', 'text/javascript');
  script.src = src;
  document.body.appendChild(script);
}

window.onload = function () {
  addScriptTag('http://example.com/ip?callback=foo');
}

function foo(data) {
  console.log('Your public IP address is: ' + data.ip);
};
Script[crossOrigin]

Script标签的crossOrigin属性具有以下的值:

  • anonymous:进行跨源请求,但不发送用户凭据(如 Cookie、HTTP 认证信息等)。
  • use-credentials:进行跨源请求,并发送用户凭据。

虽然Script标签不受同源限制,但也有一些功能限制,例如无法拿到加载错误信息,不能对DOM进行操作,此时crossOrigin字段可以解决这些问题:

  1. 错误处理:设置 crossOrigin 属性可以让浏览器提供更详细和准确的跨域脚本加载错误信息,有助于开发人员进行调试和错误排查。
  2. 资源共享和缓存:通过正确设置 crossOrigin ,可以更好地利用浏览器的缓存机制。当多个页面使用相同的跨域脚本且设置相同时,浏览器可以更有效地缓存和复用这些资源。
  3. 凭证传递:如果需要在跨域请求中传递用户凭证(如 Cookie、HTTP 认证信息等),就需要通过设置 crossOrigin="use-credentials" 来明确告知浏览器。
  4. 符合 CORS 规范:遵循跨源资源共享(CORS)的规范和最佳实践,确保跨域请求的安全性和可预测性。

WebSocket

WebSocket 协议不受同源策略的限制,可以实现跨域的双向通信

XHR

XMLHttpRequest 对象

Ajax

Fetch

Axios

基于 MIT 许可发布