前端如何调用后端接口(HTML + JS & Vue )
本文将以 Go 语言后端 为例,详细介绍:
- Go 后端接口如何设计
- 接口的请求 / 响应结构
- 前端如何用 HTML + JS 调用 Go 接口
- 前端如何用 Vue 工程模式 调用 Go 接口
- 两种方式的区别与适用场景
一、整体架构说明
前后端分离架构
浏览器
|
| HTTP 请求(JSON)
↓
前端(HTML / Vue)
|
| HTTP 请求
↓
Go 后端(API)
|
| JSON 响应
↓
前端渲染页面
- 前端:负责 页面 + 交互
- 后端(Go):负责 业务逻辑 + 数据处理
- 通信方式:HTTP + JSON
二、Go 后端接口准备
先准备一个最简单但标准的 Go 接口,方便前端调用。
一个示例接口:用户登录
接口信息
| 项目 | 内容 |
|---|---|
| URL | /user/login |
| 方法 | POST |
| 请求类型 | application/json |
| 返回类型 | application/json |
Go 后端代码示例
package main import ( "encoding/json" "net/http" ) type LoginRequest struct { Username string `json:"username"` Password string `json:"password"` } type Response struct { Code int `json:"code"` Msg string `json:"msg"` Data interface{} `json:"data,omitempty"` } func login(w http.ResponseWriter, r *http.Request) { // 只允许 POST if r.Method != http.MethodPost { w.WriteHeader(http.StatusMethodNotAllowed) return } var req LoginRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { json.NewEncoder(w).Encode(Response{ Code: 400, Msg: "参数错误", }) return } // 模拟校验 if req.Username == "admin" && req.Password == "123456" { json.NewEncoder(w).Encode(Response{ Code: 200, Msg: "登录成功", Data: map[string]string{ "token": "mock-token-123", }, }) return } json.NewEncoder(w).Encode(Response{ Code: 401, Msg: "用户名或密码错误", }) } func main() { http.HandleFunc("/user/login", login) http.ListenAndServe(":8080", nil) } 启动后端后,接口地址为:
http://localhost:8080/user/login三、HTML + JavaScript 调用 Go 接口
这是最原始、最直观的方式,非常适合:
- 学习 HTTP 请求本质
- 不使用前端框架的简单项目
- 理解 fetch / axios 的底层思想
1. HTML 页面结构
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>登录页面</title> </head> <body> <h2>用户登录</h2> <form> <div> <input type="text" placeholder="用户名"> </div> <div> <input type="password" placeholder="密码"> </div> <button type="submit">登录</button> </form> <script src="login.js"></script> </body> </html> 2. JavaScript 调用 Go 接口
const form = document.getElementById('loginForm'); form.addEventListener('submit', async function (e) { e.preventDefault(); // 阻止表单刷新页面 const username = document.getElementById('username').value; const password = document.getElementById('password').value; try { const res = await fetch('http://localhost:8080/user/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) }); const data = await res.json(); if (data.code === 200) { alert('登录成功,token:' + data.data.token); } else { alert(data.msg); } } catch (err) { console.error(err); alert('请求失败'); } }); 3.代码流程
监听表单提交阻止浏览器默认刷新获取输入框数据使用fetch发送 HTTP 请求请求体转成 JSON解析 Go 返回的 JSON根据code判断成功或失败
4. HTML + JS 的特点
✅ 优点:
- 简单直接
- 学习成本低
- 无需工程化
❌ 缺点:
- 代码容易混乱
- 不适合复杂项目
- 不利于组件复用
四、Vue 工程模式调用 Go 接口
这是实际开发中最常用的方式。
1、Vue 项目基本结构
使用 Vite 创建 Vue 项目后,常见结构:
src/ ├── api/ # 所有接口请求 │ └── user.js ├── views/ # 页面 │ └── Login.vue ├── main.js
2、Vue 中封装 API 请求
安装 axios
npm install axios3. 创建 axios 实例(src/api/request.js)
import axios from 'axios' const request = axios.create({ baseURL: 'http://localhost:8080', timeout: 5000 }) export default request 4. 用户接口封装(src/api/user.js)
import request from './request' export function login(data) { return request({ url: '/user/login', method: 'post', data }) }5、Vue 页面中调用 Go 接口
Login.vue
<template> <div> <h2>用户登录</h2> <input v-model="username" placeholder="用户名" /> <input v-model="password" type="password" placeholder="密码" /> <button @click="handleLogin">登录</button> </div> </template> <script setup> import { ref } from 'vue' import { login } from '@/api/user' const username = ref('') const password = ref('') const handleLogin = async () => { try { const res = await login({ username: username.value, password: password.value }) if (res.data.code === 200) { alert('登录成功') console.log(res.data.data.token) } else { alert(res.data.msg) } } catch (err) { alert('请求失败') } } </script> 五、Vue 调用流程总结
- 页面触发点击事件
- 调用封装好的 API 方法
- axios 发送 HTTP 请求
- Go 后端处理并返回 JSON
- Vue 根据返回结果更新 UI
六、前端调用 Go 接口时跨域问题
在实际开发中,很多同学在 HTML / Vue 调用 Go 接口 时,会在浏览器控制台看到类似错误:
Access to fetch at 'http://localhost:8080/user/login' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy
这并不是 Go 代码写错,而是 浏览器的安全机制:跨域限制(CORS)。
1.什么是跨域?
浏览器规定:
当前页面的“协议 + 域名 + 端口”必须和接口一致,否则就是跨域。
| 前端页面 | 后端接口 | 是否跨域 |
|---|---|---|
http://localhost:8080/login.html | http://localhost:8080/user/login | ❌ 否 |
http://127.0.0.1:5500/login.html | http://localhost:8080/user/login | ✅ 是 |
file:///login.html | http://localhost:8080/user/login | ✅ 是 |
只要 有一个不一样,浏览器就会认为是跨域。
2.为什么 Vue / HTML 调用时容易跨域?
- HTML 用 Live Server(5500 端口)
- Vue 开发服务器(5173 端口)
- Go 后端监听(8080 端口)
端口不同 = 跨域
3. 跨域不是 Go 限制,而是浏览器限制
重点理解这句话:
❗ 跨域请求其实已经发到 Go 服务器了
❗ 是浏览器不让前端代码拿到响应
所以解决方案一定是:
后端告诉浏览器:我允许你访问
4. Go 后端开启 CORS(通用做法)
1)最基础的 CORS 处理函数
func enableCORS(w http.ResponseWriter) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Headers", "Content-Type") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS") } 2)在接口中使用(必须支持 OPTIONS)
func login(w http.ResponseWriter, r *http.Request) { enableCORS(w) // 预检请求,直接返回 if r.Method == http.MethodOptions { return } // 正常登录逻辑 } 5.为什么一定要处理 OPTIONS 请求?
当你:
- 使用
POST - 并且
Content-Type: application/json
浏览器会先发一个 OPTIONS 预检请求:
OPTIONS /user/login
如果后端不处理:
正式请求不会发送
6.Vue 项目中的跨域
Vue 开发阶段通常通过 代理解决跨域:
// vite.config.js export default { server: { proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } } } 七、HTML + JS vs Vue
| 对比项 | HTML + JS | Vue |
|---|---|---|
| 学习成本 | 低 | 中 |
| 工程化 | ❌ | ✅ |
| 代码组织 | 差 | 好 |
| 适合项目 | 小 demo | 中大型项目 |
八、结语
无论你使用 HTML + JS 还是 Vue:
本质都是:前端通过 HTTP 请求调用 Go 接口
理解了:
- 请求方法(GET / POST)
- JSON 数据格式
- 接口返回结构
你就掌握了前后端对接的核心能力。