技术探索与实践总结:从零开始搭建一个前后端分离的项目
大家好,我是一名从培训班出来的前端开发。回想当初刚入行的时候,面对“前端”“后端”“SpringBoot”这些词,真的是一头雾水。尤其是看到别人随口说“我们用前后端分离架构”,我只能默默点头,心里却在想:“这到底是个啥?”
今天写这篇教程,就是想用最直白的语言、最贴近实战的例子,带完全零基础的朋友走通一个完整的技术探索与实践流程。
我们不讲空泛理论,只做能跑起来的代码;我们不堆术语,只解决你明天上班可能遇到的问题。
一、这个技术组合到底是干啥的?
简单来说:
- 前端(Frontend):用户看得见、摸得着的部分,比如网页上的按钮、列表、弹窗。
- JavaScript(JS):前端的核心编程语言,用来让网页“动起来”。
- SpringBoot:Java生态里最流行的后端框架,用来处理数据、连接数据库、提供接口。
- 项目(Project):把前端和后端组合起来,完成一个有实际功能的小应用。
💡 我当初学的时候以为前端就是切图+写样式,后来才知道,真正的前端还要和后端“对话”——通过 API 获取数据。而 SpringBoot 就是后端给我们提供 API 的工具。
我们的目标:用 JavaScript 写一个前端页面,向 SpringBoot 后端请求数据,并展示出来。
二、环境准备:5 分钟搭好开发环境
1. 安装必要软件
| 软件 | 用途 | 安装建议 |
|---|---|---|
| Node.js | 运行 JavaScript 项目 | 去 nodejs.org 下载 LTS 版本 |
| JDK 17 或以上 | 运行 Java/SpringBoot | 推荐使用 OpenJDK |
| VS Code | 编写代码 | 免费,插件丰富 |
| Postman(可选) | 测试后端接口 | 新手调试神器 |
✅ 检查是否安装成功:
node -v # 应输出 v18.x 或更高 java -version # 应显示 openjdk 17+
2. 创建前端项目(使用 Vite)
Vite 是目前最轻快的前端构建工具,适合新手。
# 创建项目
npm create vite@latest my-frontend -- --template vanilla
# 进入目录并安装依赖
cd my-frontend
npm install
# 启动开发服务器
npm run dev
打开浏览器访问 http://localhost:5173,看到 “Hello world” 就成功了!
3. 创建后端项目(SpringBoot)
推荐使用 Spring Initializr 在线生成项目。
- Project: Maven
- Language: Java
- Spring Boot: 3.x
- Dependencies: Spring Web
下载 ZIP 后解压,用 VS Code 打开(需安装 Java Extension Pack)。
启动方式(终端进入项目目录):
./mvnw spring-boot:run
看到 Tomcat started on port(s): 8080 表示后端启动成功。
⚠️ 注意:前后端默认端口不同(前端 5173,后端 8080),这就是“跨域”,后面我们会处理。
三、核心概念:用大白话解释技术名词
1. 前后端分离是什么?
想象你去餐厅吃饭:
- 前端 = 服务员(负责和你沟通,展示菜单)
- 后端 = 厨房(负责做菜,管理食材)
- API = 点菜单(服务员把你的需求写下来,传给厨房)
前后端通过 HTTP 请求(比如 GET、POST)传递“点菜单”。
2. JavaScript 如何请求数据?
用浏览器内置的 fetch 函数:
// 前端代码:向后端要数据
fetch('http://localhost:8080/api/hello')
.then(response => response.json())
.then(data => {
console.log(data.message); // 比如打印 "Hello from backend!"
});
3. SpringBoot 如何提供接口?
在 SpringBoot 中,用 @RestController 标记一个类,用 @GetMapping 标记方法:
// 后端代码:提供接口
@RestController
public class HelloController {
@GetMapping("/api/hello")
public Map<String, String> sayHello() {
Map<String, String> result = new HashMap<>();
result.put("message", "Hello from backend!");
return result;
}
}
🌟 关键点:前端请求
/api/hello,后端返回 JSON 数据。
四、实战项目:做一个“每日名言”展示器
我们要实现的功能:页面加载时,自动从后端获取一句名言并显示。
第一步:完善后端接口
修改 HelloController.java:
import org.springframework.web.bind.annotation.*;
import java.util.*;
@RestController
public class QuoteController {
private static final List<String> QUOTES = Arrays.asList(
"Stay hungry, stay foolish.",
"The only way to do great work is to love what you do.",
"Innovation distinguishes between a leader and a follower."
);
@GetMapping("/api/quote")
public Map<String, String> getRandomQuote() {
Random rand = new Random();
String quote = QUOTES.get(rand.nextInt(QUOTES.size()));
Map<String, String> result = new HashMap<>();
result.put("quote", quote);
return result;
}
}
重启 SpringBoot 项目。
🔍 测试接口:打开浏览器访问
http://localhost:8080/api/quote,应该看到类似:{"quote":"Stay hungry, stay foolish."}
第二步:编写前端页面
修改 my-frontend/index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>每日名言</title>
<style>
body { font-family: Arial; text-align: center; padding-top: 50px; }
#quote { font-size: 24px; color: #333; margin-top: 20px; }
button { padding: 10px 20px; font-size: 16px; margin-top: 20px; }
</style>
</head>
<body>
<h1>✨ 每日名言 ✨</h1>
<div id="quote">点击按钮获取名言...</div>
<button onclick="fetchQuote()">获取新名言</button>
<script type="module" src="/main.js"></script>
</body>
</html>
创建或修改 main.js:
async function fetchQuote() {
try {
const response = await fetch('http://localhost:8080/api/quote');
const data = await response.json();
document.getElementById('quote').innerText = data.quote;
} catch (error) {
console.error('请求失败:', error);
document.getElementById('quote').innerText = '网络错误,请重试';
}
}
// 页面加载时自动获取一次
fetchQuote();
第三步:解决跨域问题(关键!)
由于前端(5173)和后端(8080)端口不同,浏览器会阻止请求(CORS 策略)。
解决方案:在 SpringBoot 中添加跨域配置。
新建文件 CorsConfig.java:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:5173")
.allowedMethods("GET", "POST");
}
}
✅ 这样,来自
http://localhost:5173的请求就能访问/api/**开头的接口了。
重启后端,刷新前端页面——名言应该正常显示了!
五、新手常见问题 & 解决方案
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
前端请求报错 CORS error |
跨域未配置 | 检查 SpringBoot 是否添加了 CorsConfig |
页面空白,控制台报错 Failed to fetch |
后端没启动 | 确保 ./mvnw spring-boot:run 正在运行 |
后端启动报错 Port 8080 already in use |
端口被占用 | 修改 application.properties 添加 server.port=8081 |
fetch 返回 undefined |
没有调用 .json() |
记住:response.json() 是异步的,必须 await |
| Java 项目无法导入 | 缺少 Maven 插件 | 在 VS Code 安装 “Extension Pack for Java” |
💡 我当初学的时候,光跨域问题就卡了两天。后来明白:前端请求 ≠ 直接访问 URL,必须后端允许才行。
六、性能优化小技巧(贴合主题)
虽然项目简单,但我们可以提前养成好习惯:
1. 前端:避免重复请求
// 添加 loading 状态,防止用户狂点按钮
let isLoading = false;
async function fetchQuote() {
if (isLoading) return;
isLoading = true;
// ...请求逻辑
isLoading = false;
}
2. 后端:接口响应加缓存(可选)
对不变的数据,可用 @Cacheable(需引入 Spring Cache),但本例数据量小,暂不需要。
3. 网络:使用更现代的 HTTP/2(生产环境)
本地开发无需关心,部署时 Nginx 配置即可。
七、下一步学习建议
你已经完成了:
- 搭建前后端环境
- 实现数据通信
- 解决跨域问题
接下来可以探索:
- 前端进阶:学 Vue 或 React(Vite 支持它们一键创建)
- 后端深化:连接真实数据库(H2 / MySQL),用 JPA 操作数据
- 部署上线:用 Docker 容器化,部署到云服务器
- 工具链:Git 版本控制、GitHub Actions 自动化
📌 我的建议:不要贪多,先把今天这个项目自己从头到尾敲一遍。遇到报错别慌,90% 的问题都是拼写错误或服务没启动。
结语
这篇教程源于我当初踩过的坑。培训班教语法,但没人告诉我“前后端怎么连起来”。现在你已经迈出了最关键的一步——让两个世界对话。
记住:所有复杂的系统,都是由一个个像“获取一句名言”这样的小功能组成的。保持动手,保持好奇,你离“真正的开发者”就不远了。
最后送你一句我们项目的名言:
“The only way to do great work is to love what you do.”
—— Steve Jobs
加油,未来的全栈工程师!

评论 0