你在浏览器输入一个网址,到底发生了什么?

1)你在浏览器输入一个网址,到底发生了什么?

你在地址栏输入:

https://www.example.com

浏览器大致会做这些事:

  1. DNS 解析 :把 www.example.com 解析成服务器 IP
  2. 建立连接:HTTP/HTTPS(HTTPS 还会做 TLS 握手)
  3. 发送 HTTP 请求 :例如 GET /
  4. 服务器返回响应:通常返回一个 HTML
  5. 浏览器解析 HTML,发现还需要:
    • CSS、JS、图片、字体等资源 → 再发请求
  6. JS 运行后,可能还会请求后端接口(比如 /api/user)获取数据

这就引出两个核心对象:

  • 前端静态文件:HTML/CSS/JS/图片等(通常就是"资源文件")
  • 后端接口服务:提供数据的 API(通常返回 JSON)

2)什么是"前端静态文件"?和浏览器什么关系?

2.1 静态文件是什么

所谓"静态",是相对"动态生成"而言:

  • 静态文件 :服务器几乎不需要计算,直接把文件原样发给你
    例:index.htmlapp.jsstyle.csslogo.png
  • 动态内容(后端) :服务器要运行代码、查数据库、计算后再返回
    例:GET /api/orders 返回订单 JSON

2.2 浏览器为什么需要静态文件

浏览器本质上做三件事:

  • 渲染 HTML → 得到页面结构
  • 应用 CSS → 得到样式
  • 执行 JS → 让页面"活起来",比如点击按钮、发请求、更新页面

所以前端静态文件是浏览器"建页面 + 交互"的原材料。


3)前端项目为什么要"构建/打包"?(你可能未知但很关键)

现代前端(Vue/React 等)开发时写的代码,不一定能直接给浏览器用,需要"构建":

  • 你写:模块化代码、TypeScript、Sass、拆分组件......
  • 构建工具(Vite/Webpack)输出:浏览器可直接加载的一堆静态文件
    常见产物:
    • dist/index.html
    • dist/assets/app.xxx.js
    • dist/assets/app.xxx.css

部署前端 通常就是:把 dist 目录放到服务器上,用 Nginx/对象存储/CDN 对外提供下载。


4)Nginx 是什么?它到底做了哪些事?

你可以把 Nginx 先当成一个非常高性能的"门口接待 + 分发系统",常见能力:

  1. 提供静态文件 (直接把 index.html、JS、CSS 发给浏览器)
  2. 反向代理/转发(reverse proxy):把某些请求转交给后端服务
  3. 负载均衡:后端有很多台机器,Nginx 帮你分摊
  4. HTTPS 终止:证书放 Nginx,上游后端走 HTTP
  5. 设置安全头/缓存策略/压缩

4.1 "转发/反向代理"到底是什么?

你可能听过"代理"。区分一下:

  • 正向代理:帮"客户端"代理访问(例如某些网络代理)
  • 反向代理:帮"服务器端"代理,把请求转到内部服务(Nginx 常做这个)

举例:浏览器访问

  • https://www.example.com/ → Nginx 返回前端静态文件
  • https://www.example.com/api/user → Nginx 转发给后端 http://127.0.0.1:8080/api/user

对浏览器来说,它只知道自己访问的是同一个域名 www.example.com


5)前端怎么访问后端?"怎么通"的完整链路

以典型"单域名"部署为例:

  1. 浏览器打开 https://www.example.com/
    → Nginx 返回 index.html 等静态资源

  2. 页面 JS 启动后,调用接口:

    复制代码

    js

    fetch('/api/user')

  3. 浏览器发请求到 https://www.example.com/api/user

  4. Nginx 看到路径以 /api/ 开头
    反向代理到后端服务(比如 Spring Boot/Node/Python)

  5. 后端处理请求(鉴权、查库、业务逻辑)
    → 返回 JSON

  6. Nginx 把 JSON 回给浏览器

  7. 浏览器 JS 拿到 JSON,渲染到页面上

这就是"前后端通了"。


6)跨域(CORS)到底在解决什么?为什么会发生?

6.1 什么是"同源策略"(跨域的根)

浏览器有一个安全机制:同源策略

"源(origin)"由三部分决定:

  • 协议:http/https
  • 域名:a.com
  • 端口::80/:443/:3000

只要这三者有任意不同,就不是同源。

比如:

  • 前端页面来自:http://localhost:5173
  • 后端接口是:http://localhost:8080

这就不同源,浏览器会限制前端 JS 直接读取接口响应,除非后端明确允许。

注意:跨域是浏览器的限制,不是服务器不让你访问。你用 curl/postman 没事,但浏览器 JS 会被拦。

6.2 CORS 是什么

CORS(跨域资源共享)是让后端通过响应头告诉浏览器:"我允许这个源来访问我"。

常见头:

  • Access-Control-Allow-Origin: http://localhost:5173(或 *
  • Access-Control-Allow-Credentials: true(允许带 cookie/凭证)
  • 预检请求相关:
    • Access-Control-Allow-Methods
    • Access-Control-Allow-Headers

6.3 为什么会有"预检 OPTIONS"?

当你发的请求"复杂"时(例如 PUT/DELETE、自定义 Header、JSON Content-Type 等),浏览器会先发一个 OPTIONS 请求问后端:你允许吗?这就是预检。

6.4 实战里怎么最省心?

开发/部署常用两种方案:

方案 A:前后端同域(推荐,最省心)

通过 Nginx 把 /api 代理到后端,这样浏览器看到的都是同域请求,就几乎不涉及 CORS。

方案 B:不同域/不同端口(需要 CORS)

比如前端 a.com 后端 api.a.comlocalhost:5173 vs localhost:8080,就要后端(或网关/Nginx)配 CORS。


7)"路径问题"你到底在困惑什么?

路径问题通常有三类:

7.1 前端路由(SPA)刷新 404

Vue/React 单页应用(SPA)里,/user/profile 这种"路由"是前端 JS 处理的。

但当你刷新页面时,浏览器会向服务器请求:

复制代码

GET /user/profile

服务器如果只会找静态文件,发现没有 /user/profile 这个文件,就 404。

解决:Nginx 配置"回退到 index.html"(history 模式必备)

意思是:除了静态资源和 API,其他路径都返回 index.html,让前端路由接管。

7.2 代理转发时的路径拼接(/api 是否保留)

例如:

  • 浏览器请求:/api/user
  • 你希望后端收到:/user 还是 /api/user

Nginx 配置里 proxy_pass 是否带尾 / 会影响这件事(这是新手很容易踩坑的点)。

7.3 前端资源相对路径/绝对路径

index.html 里引用 JS/CSS 时,用相对路径还是绝对路径,会影响部署到子目录、CDN 时能否加载。


8)iframe 安全头你提到的是什么?解决什么风险?

iframe 可以把一个页面嵌入另一个页面。风险之一是:

  • 你的网站被别人用 iframe 套在自己的页面里,做"点击劫持"(用户以为点的是你的按钮,其实被引导做别的事)

常见防护响应头:

8.1 X-Frame-Options(老但常见)

  • DENY:完全不允许任何站点 iframe 你
  • SAMEORIGIN:只允许同源页面 iframe 你
  • ALLOW-FROM:基本被现代浏览器淘汰

8.2 Content-Security-Policy: frame-ancestors(更现代)

例如:

  • Content-Security-Policy: frame-ancestors 'self' https://partner.com;

这比 X-Frame-Options 更灵活,是推荐做法。


9)除了你提到的,你还"必须知道"的几个关键点

9.1 Cookie/Session vs Token(登录鉴权怎么带)

前端请求后端时,经常涉及登录态:

  • Cookie + Session:浏览器自动带 Cookie;跨域时更麻烦(要 CORS + credentials)
  • JWT/Token :前端把 token 放在请求头(如 Authorization: Bearer ...)或其他位置

这决定了你怎么配 Nginx/CORS,以及安全策略。

9.2 HTTP 与 HTTPS 的差别

  • HTTPS 会加密,防中间人篡改
  • 混合内容:HTTPS 页面里请求 HTTP 接口会被浏览器拦(常见坑)

9.3 缓存(为什么改了代码但浏览器没更新)

静态资源常会被强缓存。现代构建用 hash 文件名(app.8f3a.js)解决缓存更新问题。Nginx/浏览器缓存策略很关键。

9.4 CDN(静态资源加速)

很多公司把静态资源放 CDN;API 走主站/网关。理解"静态资源"和"接口"天然适合分开部署。


10)给你一张"最常见架构"的心智图(文字版)

一个典型线上结构:

  • 浏览器
    → 访问 https://www.example.com
  • Nginx(或网关)
    • //assets/* → 返回前端静态文件
    • /api/* → 反向代理到后端服务集群
    • 设置安全头(CSP、HSTS、X-Frame-Options 等)
    • 可能做压缩、缓存、限流
  • 后端服务
    • 鉴权、业务逻辑、访问数据库/缓存
  • 数据库/缓存

这套结构解决了:

  • 前端资源如何给浏览器
  • 前端如何"同域"访问后端
  • 跨域问题如何避免或处理
  • 路由刷新 404 如何解决
  • iframe 相关安全如何控制
相关推荐
前端Hardy1 天前
面试官:JS数组的常用方法有哪些?这篇总结让你面试稳了!
javascript·面试
yuki_uix1 天前
Props、Context、EventBus、状态管理:组件通信方案选择指南
前端·javascript·react.js
日月云棠1 天前
各版本JDK对比:JDK 25 特性详解
java
全栈老石1 天前
手写无限画布4 —— 从视觉图元到元数据对象
前端·javascript·canvas
用户8307196840821 天前
Spring Boot 项目中日期处理的最佳实践
java·spring boot
JavaGuide1 天前
Claude Opus 4.6 真的用不起了!我换成了国产 M2.5,实测真香!!
java·spring·ai·claude code
Leon1 天前
新手引导 intro.js 的使用
前端·javascript·vue.js
IT探险家1 天前
Java 基本数据类型:8 种原始类型 + 数组 + 6 个新手必踩的坑
java
花花无缺1 天前
搞懂new 关键字(构造函数)和 .builder() 模式(建造者模式)创建对象
java
用户908324602731 天前
Spring Boot + MyBatis-Plus 多租户实战:从数据隔离到权限控制的完整方案
java·后端