【前端面试】三次握手/http/https,是否跳转携带cookie,跨域

TCP三次握手

  • TCP三次握手是为了在客户端和服务器之间建立可靠的连接。首先,客户端向服务器发送一个SYN包,请求建立连接,并进入SYN_SENT状态;服务器收到SYN包后,回复一个SYN+ACK包,表示同意建立连接,并进入SYN_RECV状态;客户端收到SYN+ACK包后,再向服务器发送一个ACK包,确认连接建立,双方进入ESTABLISHED状态,此时连接建立成功,可以开始传输数据。

HTTP请求

  • HTTP请求由客户端发起,用于向服务器请求资源。一个完整的HTTP请求包括请求行、请求头、空行和请求体。请求行包含请求方法(如GET、POST等)、请求的URL和HTTP协议版本;请求头包含各种附加信息,如用户代理、接受的内容类型等;空行用于分隔请求头和请求体;请求体则是在POST等请求方法中向服务器发送的数据。

HTTPS

  • 加密原理:HTTPS在HTTP的基础上加入了SSL/TLS协议,通过非对称加密和对称加密相结合的方式对数据进行加密。在连接建立初期,客户端和服务器通过非对称加密算法交换密钥,然后使用对称加密算法对数据进行加密传输,这样既保证了密钥交换的安全性,又提高了加密和解密的效率.
  • 优势:安全性高,能防止数据在传输过程中被窃取、篡改,确保数据的完整性和保密性,还可通过数字证书验证服务器身份,防止中间人攻击;在搜索引擎优化方面,搜索引擎偏爱HTTPS网站,其在搜索结果中的排名可能更靠前.
  • 性能影响:由于需要加密和解密数据,HTTPS的性能相对HTTP略差,连接速度会稍慢一些,但随着硬件性能的提升和加密算法的优化,这种性能差异在大多数情况下并不明显.
  • 成本方面:HTTPS需要购买SSL证书,尤其是对于需要高级别安全认证的网站,证书费用可能较高。同时,部署和维护HTTPS也需要一定的技术知识和资源投入.

跳转是否携带cookie

是否 b 页面 会带 a 页面的 cookie,取决于以下几个因素:

1. 是否同域

  • 同域跳转 :如果 a 页面b 页面 在同一个域名、协议(http/https)和端口下,那么浏览器会自动携带 a 页面 的 cookie 到 b 页面

    • 例如:
      • a 页面:https://example.com/a
      • b 页面:https://example.com/b
    • 在这种情况下,跳转到 b 页面 时,浏览器会携带 example.com 域下的所有有效 cookie
  • 跨域跳转 :如果 a 页面b 页面 不在同一个域名下,那么浏览器会遵循 同源策略a 页面 的 cookie 通常不会自动携带到 b 页面,除非设置了跨域 cookie 相关的正确属性。

    例如:

    • a 页面:https://siteA.com/a
    • b 页面:https://siteB.com/b
    • 在这种情况下,a 页面 的 cookie 不会 自动带到 b 页面,除非以下条件满足。

2. SameSite 属性

这个属性控制 cookie 是否会在跨站请求中携带:

  • SameSite=Lax :cookie 仅在同一站点的请求中发送,部分跨站请求(如 GET 请求)也会发送 cookie,但 POST 请求等会被阻止。如果 a 页面b 页面 在同一站点且是 GET 请求,cookie 会被带上。
  • SameSite=Strict :cookie 只在同一站点的请求中发送,跨站请求(即从 https://siteA.com 跳转到 https://siteB.com)不会发送该 cookie。
  • SameSite=None :cookie 会在所有跨站请求中发送,但必须加上 Secure 标记,并且请求必须通过 HTTPS 发起。

结论:

  • 如果 SameSite=LaxSameSite=Strict ,那么跨域跳转时,a 页面 的 cookie 不会 被携带到 b 页面
  • 如果 SameSite=NoneSecure ,并且 b 页面 的请求是通过 HTTPS 发起的,那么 a 页面 的 cookie 被带到 b 页面,即使它们处于不同的域。

3. Secure 标志

  • 如果 cookie 设置了 SameSite=None,那么该 cookie 也必须使用 Secure 标志,即必须通过 HTTPS 传输。
  • 如果 a 页面 的 cookie 没有 Secure 标志,而是跨域跳转到 b 页面 ,那么 a 页面 的 cookie 即使设置为 SameSite=None,也不会发送。

4. 跨域请求(例如,通过 JavaScript 跳转)

如果你通过 JavaScript 来跳转页面(如 window.location.href),浏览器的行为与点击普通的 <a> 标签链接一样。浏览器会检查 cookie 的 SameSite 属性,决定是否携带 cookie。如果是跨域跳转,a 页面 的 cookie 会根据上述规则(SameSiteSecure)决定是否携带。

5. 浏览器的隐私策略

现代浏览器(如 Chrome 和 Firefox)对 第三方 cookie 进行了更严格的限制。例如,如果 a 页面b 页面 不在同一个域下,浏览器可能会默认阻止跨站 cookie 的发送,除非明确允许。因此,即使设置了 SameSite=NoneSecure,某些浏览器仍然可能因为隐私策略而阻止 cookie 发送。

总结:

  • 同域跳转b 页面会带上 a 页面的 cookie。
  • 跨域跳转 :如果 ab 是不同的域,且 a 页面的 cookie 设置了 SameSite=NoneSecure 标记,浏览器会在跳转时携带 a 页面的 cookie 到 b 页面。否则,cookie 不会被携带。
  • 浏览器隐私策略 :某些浏览器可能会阻止第三方 cookie 的发送,尤其是在跨域的情况下。
    以下是一些常见的解决跨域问题的方法:

1. JSONP(JSON with Padding)

  • 原理 :利用<script>标签的跨域特性。浏览器允许<script>标签引用不同域的脚本文件。JSONP通过动态创建<script>标签,将一个回调函数名作为参数传递给跨域的服务器接口。服务器返回的数据会包裹在这个回调函数中,在浏览器端执行,从而实现跨域获取数据。
  • 适用场景:主要用于GET请求,适用于获取一些简单的公开数据,如获取天气预报数据、公共的新闻列表等。
  • 示例代码(在JavaScript中)
javascript 复制代码
function jsonpCallback(data) {
    console.log(data);
}
var script = document.createElement('script');
script.src = 'https://example.com/api?callback=jsonpCallback';
document.getElementsByTagName('head')[0].appendChild(script);

2. CORS(跨域资源共享)

  • 原理 :是一种现代浏览器支持的跨域解决方案。服务器通过在响应头中设置Access - Control - Allow - Origin等相关字段,来允许指定的源(域名)访问资源。它可以实现更安全、更灵活的跨域请求,支持多种HTTP请求方法(GET、POST等)。
  • 适用场景:适用于前后端分离的项目,在服务器能够控制响应头设置的情况下广泛使用,如Web API开发等场景。
  • 示例代码(在服务器端,以Node.js为例)
javascript 复制代码
const http = require('http');
const server = http.createServer((req, res) => {
    res.setHeader('Access - Control - Allow - Origin', '*'); 
    res.setHeader('Access - Control - Allow - Methods', 'GET, POST');
    res.setHeader('Access - Control - Allow - Headers', 'Content - Type');
    // 处理具体请求逻辑
    //...
});
server.listen(3000);
  • 注意点 :如果要在跨域请求中携带Cookie等凭证信息,还需要设置Access - Control - Allow - Credentials: true,并且在前端请求时设置credentials: 'include'

3. 代理服务器

  • 原理:在前端和后端之间设置一个代理服务器。前端请求发送到代理服务器,代理服务器再将请求转发给实际的后端服务器。因为前端和代理服务器通常在同一域内,所以不存在跨域问题。代理服务器获取后端服务器的响应后,再将其返回给前端。
  • 适用场景 :在开发环境下经常使用,例如使用Webpack的dev - server作为代理服务器。也适用于对安全性和隐私要求较高的场景,通过代理服务器可以对请求和响应进行过滤和控制。
  • 示例代码(在Webpack配置文件中)
javascript 复制代码
module.exports = {
    //...
    devServer: {
        proxy: {
            '/api': {
                target: 'https://backend - server - domain.com',
                changePath: true,
                pathRewrite: {
                    '^/api': ''
                }
            }
        }
    }
};

这会将前端以/api开头的请求代理到https://backend - server - domain.com服务器。

相关推荐
范文杰3 分钟前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪11 分钟前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪19 分钟前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy1 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom2 小时前
快速开始使用 n8n
后端·面试·github
uhakadotcom2 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom2 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom2 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom2 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom2 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试