【前端开发】你的 fetch 到底是在哪里发起的?揭秘 Next.js 服务端渲染?
写给 Python/Go 开发者的前端速通(3):你的 fetch 到底是在哪里发起的?揭秘 Next.js 服务端渲染
在[上一篇文章]中,我们解剖了前端页面组件的“工厂流水线”,并看到了这样一段发起网络请求的核心代码:
// 进货渠道
async function getAthletes(): Promise<Athlete[]> {
const res = await fetch('http://localhost:8080/api/athletes');
return res.json() as Promise<Athlete[]>;
}
// 页面组件
export default async function AthletesPage() {
const athletes = await getAthletes();
return ( <div>...渲染列表...</div> );
}
代码看懂了,但对于习惯了写后端 API 的 Python/Go 开发者来说,这里藏着一个巨大的盲区,也是现代前端最容易让人懵逼的问题:
这段 fetch 代码,到底是在用户的浏览器(手机/电脑)里执行的,还是在前端的服务器上执行的?
搞懂这个问题,你才算真正跨过了现代前端(React / Next.js)的门槛。今天我们就来把这个“黑盒”彻底打开。
时代眼泪:传统的 CSR(客户端渲染)
如果这段代码放在几年前的传统 React (Create React App) 或 Vue 项目中,它的执行逻辑是这样的(客户端渲染 Client-Side Rendering):
- 用户在浏览器输入网址。
- 前端服务器直接扔给浏览器一个几乎空白的 HTML 和一个巨大的 JS 文件。
- 浏览器下载完 JS,开始执行代码。
- 浏览器(用户的电脑/手机) 里的 JS 代码发起了
fetch('http://localhost:8080...')。 - 你的 Go 后端收到请求,返回 JSON。
- 浏览器拿到 JSON,用 JS 动态生成 HTML,页面才终于显示出运动员列表。
后端的痛点:
- 跨域(CORS)地狱:因为是用户的浏览器直接请求你的 Go 服务器,如果域名不同,浏览器会直接拦截,把你折腾得死去活来。
- 白屏时间长:网速慢的手机上,用户要看很久的“加载中…”。
- SEO 灾难:百度/谷歌的爬虫拿到的是空白 HTML,根本不知道你的网页里有啥。
降维打击:Next.js 的 RSC(React 服务端组件)
回到我们这套代码!仔细看组件定义:export default async function AthletesPage()。
请注意这个 async,在现代的 Next.js(App Router 模式)中,给组件加上 async,意味着它是一个 RSC(React Server Component,服务端组件)。
这意味着,这段代码根本不会在用户的浏览器里执行,而是在前端的 Node.js 服务器上执行的!
用后端的视角来看,它完美等价于 Python 的 Jinja2 或者 Go 的 html/template!
真实的请求链路是这样的:
- 用户在浏览器输入网址。
- 前端的 Node.js 服务器 收到请求,开始执行
AthletesPage函数。 - 走到
const athletes = await getAthletes()时,Node.js 服务器 在内网发起fetch,向你的 Go 后端(比如跑在同一台机器的 8080 端口)请求数据。 - Go 后端秒回 JSON 数据给 Node.js 服务器。
- Node.js 服务器拿到数据,立刻在内存里把
<li key={...}>这些 HTML 标签拼接好。 - Node.js 把拼接好数据的、完整的、纯静态的 HTML 发送给用户的浏览器。
- 浏览器收到 HTML,瞬间显示页面。
💡 为什么这种模式让后端狂喜?
一旦你理解了 getAthletes() 是在前端的 Node.js 服务器上跑的,你就会发现现代前端框架其实是对后端极其友好的:
- 没有跨域(CORS)问题了!
这是 Node.js 服务器和你的 Go 服务器之间的**服务器对服务器(Server-to-Server)**通信。根本不经过浏览器,自然就没有浏览器的同源策略限制,彻底告别 CORS 报错。 - 极度安全,可以藏 API Key!
以前在前端代码里写第三方的 API Key,等于是直接发给用户。现在由于代码在服务端执行,你可以放心地在fetch里塞各种带鉴权的 Header,浏览器端抓包绝对抓不到。 - 甚至可以直连数据库(如果不写 Go 后端的话)
因为环境在服务端,很多 Next.js 开发者甚至连外挂后端都省了,直接在这个getAthletes函数里写SELECT * FROM athletes查询 PostgreSQL 数据库。
总结与预告
前端不再仅仅是运行在浏览器里的一团 JS 脚本,现代的 Next.js 实际上是一个拥有完整服务端能力的框架。
通过这三篇帖子,我们从 TypeScript 的“数据图纸”(Interface),讲到组件的“流水线工厂”(Component & Map),再到今天揭开了“前端服务器”(SSR / RSC)的真面目。前端对你来说,应该不再是黑盒了!
当然,前线的网页再花哨,也离不开坚实的后勤保障。下一篇,我们将正式回到我们的主场——深入拆解 Go 后端的四层架构(Handler / Service / Repository / Model),看看如何写出工业级、易扩展的后端 API! 敬请期待!
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)