前端请求头前端调用后端接口时,通常需要配置请求头(Headers),这些头信息用于身份验证、跨域控制、数据格式定义等。
1.HTTP 请求头的作用HTTP 请求头(Request Headers)是客户端(浏览器、前端应用)发送 HTTP 请求时,附加的键值对信息。
作用包括:
身份认证(Authorization):携带 Token 让后端识别用户身份
数据格式声明(Content-Type / Accept):告诉服务器要发送什么格式的数据、希望返回什么格式的数据
安全性(Referer / Origin):限制请求来源,防止 CSRF 攻击
性能优化(Cache-Control):控制缓存策略,减少不必要的网络请求
跨域请求控制(Access-Control-Allow-Origin):后端允许特定域访问资源
2. 常见的请求头字段
请求头字段
作用
示例值
Authorization
认证 Token
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI...
Content-Type
请求体格式
application/json
Accept
期望的返回格式
application/json
Referer
请求来源
https://example.com
Origin
请求发起者
https://my-frontend.com
User-Agent
客户端信息
Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Cache-Control
缓存策略
no-cache, no-store, must-revalidate
X-Requested-With
标记 AJAX 请求
XMLHttpRequest
APP-DOMAIN
自定义应用标识
my-app-domain
3. 在 Vue 3 中封装全局 Axios(1) 安装 Axiosnpm install axios
(2) 创建 Axios 实例在 src/utils/request.ts(或 request.js或api/index.ts)封装 Axios,设置全局请求头:
import axios from "axios";
import { getToken, refreshToken } from "@/utils/auth"; // 获取 & 刷新 Token
// 创建Axios实例
const service = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL, // 读取环境变量配置
timeout: 10000, // 设置超时时间10s
headers: {
"Content-Type": "application/json", // 发送 JSON 格式数据
"APP-DOMAIN": "my-app", // 自定义请求头
},
})
// 请求拦截器:在请求发送前自动添加 Token
service.interceptors.request.use(
(config) => {
const token = getToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// 响应拦截器:自动处理错误 & 刷新 Token
service.interceptors.response.use(
async (response) => {
return response.data; // 直接返回后端返回的数据
},
async (error) => {
const { response } = error;
if (response) {
// **处理 401 未授权错误,尝试刷新 Token**
if (response.status === 401) {
const newToken = await refreshToken();
if (newToken) {
error.config.headers.Authorization = `Bearer ${newToken}`;
return service(error.config); // 重新请求
}
}
}
return Promise.reject(error);
}
);
export default service;
4.在 Vue 组件中使用封装的 Axiosimport http from "@/utils/request";
const fetchAuthors = async () => {
try {
const response = await http.post("/v1/site_ugc/author/get", {
phone_number: "",
status: 1,
page: 1,
size: 10,
});
console.log("API 返回的数据:", response);
} catch (error) {
console.error("请求失败:", error);
}
};
fetchAuthors();
5. 如何在 Vue 全局注册 Axios(1) Vue 3 方式在 main.ts 注册 Axios,让所有组件可以直接使用:
import { createApp } from "vue";
import App from "./App.vue";
import http from "@/utils/request";
const app = createApp(App);
app.config.globalProperties.$http = http; // 挂载到 Vue 全局
app.mount("#app");
在组件中直接使用:
this.$http.get("/api/data").then((res) => console.log(res));
(2) Vue 3 + Pinia 全局存储如果你的项目使用 Pinia 管理状态,可以在 store 里全局管理 Axios:
import { defineStore } from "pinia";
import http from "@/utils/request";
export const useApiStore = defineStore("api", {
state: () => ({
http,
}),
});
在组件中:
import { useApiStore } from "@/store/api";
const api = useApiStore();
api.http.get("/api/data").then((res) => console.log(res));
6. 如何查看请求头?(1) Chrome 开发者工具
打开网页,按 F12 或 Ctrl + Shift + I
进入 Network(网络) 选项卡
选择 Fetch/XHR
点击某个请求,在 Headers 里查看 Request Headers
(2) Console 打印在 Axios 请求拦截器里:
service.interceptors.request.use((config) => {
console.log("请求头:", config.headers);
return config;
});
7. 进阶优化(1) 防止重复请求可以使用 axios-cancel 取消重复请求:
import AxiosCancel from "@/utils/axiosCancel";
const axiosCancel = new AxiosCancel();
service.interceptors.request.use((config) => {
axiosCancel.addPending(config);
return config;
});
service.interceptors.response.use(
(response) => {
axiosCancel.removePending(response.config);
return response;
},
(error) => {
axiosCancel.removePending(error.config);
return Promise.reject(error);
}
);
(2) 自动刷新 Token如果 Token 过期,可以使用 refreshToken 自动续签:
import { getToken, refreshToken } from "@/utils/auth";
service.interceptors.response.use(
async (response) => response,
async (error) => {
if (error.response.status === 401) {
const newToken = await refreshToken();
if (newToken) {
error.config.headers.Authorization = `Bearer ${newToken}`;
return service(error.config); // 重新请求
}
}
return Promise.reject(error);
}
);
登录和验证机制1. 登录流程一般前端的登录流程如下:
用户输入 用户名+密码
前端加密(可选)后,发送到后端
后端验证用户信息,返回 Token(JWT)
前端存储 Token(localStorage/sessionStorage/cookie)
之后的请求都在请求头中携带 Token
服务器验证 Token,返回相应数据
流程图:
复制编辑[用户登录] -> [发送账号密码] -> [后端验证] -> [返回 Token]
-> [前端存储 Token] -> [请求时携带 Token] -> [后端验证 Token]
2. Token 认证(JWT)JWT(JSON Web Token)是一种常见的 Token 认证方式,Token 通常包含:
{
"alg": "HS256",
"typ": "JWT"
}
.
{
"user_id": "12345",
"role": "admin",
"exp": 1710000000
}
.
"签名"
其中:
Header(头部):算法信息
Payload(载荷):存储用户 ID、角色、过期时间
Signature(签名):防止篡改
3. Vue 实现登录(1) 创建 API 登录请求在 api/auth.ts 里封装登录接口:
import http from "@/utils/request";
export const login = (data: { username: string; password: string }) => {
return http.post("/api/login", data);
};
(2) Vue 组件实现登录
import { ref } from "vue";
import { login } from "@/api/auth";
import { useAuthStore } from "@/store/auth";
import { useRouter } from "vue-router";
const username = ref("");
const password = ref("");
const authStore = useAuthStore();
const router = useRouter();
const handleLogin = async () => {
try {
const res = await login({ username: username.value, password: password.value });
authStore.setToken(res.token); // 存储 Token
router.push("/dashboard"); // 登录成功跳转
} catch (error) {
console.error("登录失败:", error);
}
};
4. 前端存储 Token常见存储方式:
方式
特点
localStorage
页面刷新后仍存在,但易被 XSS 攻击
sessionStorage
仅在会话期间有效,关闭浏览器后清除
cookie
可设置 HttpOnly 避免 XSS,但请求会自动携带,可能被 CSRF 攻击
封装 Token 读取 & 存储在 utils/auth.ts 里:
const TOKEN_KEY = "access_token";
export const getToken = () => localStorage.getItem(TOKEN_KEY);
export const setToken = (token: string) => localStorage.setItem(TOKEN_KEY, token);
export const removeToken = () => localStorage.removeItem(TOKEN_KEY);
如果是使用cookies
直接使用 document.cookie
const TOKEN_KEY = "access_token";
// 设置 Token(带 HttpOnly 和 Secure 需后端设置)
export const setToken = (token: string, expiresDays = 7) => {
const date = new Date();
date.setTime(date.getTime() + expiresDays * 24 * 60 * 60 * 1000); // 过期时间
document.cookie = `${TOKEN_KEY}=${token}; expires=${date.toUTCString()}; path=/`;
};
// 获取 Token
export const getToken = () => {
const cookies = document.cookie.split("; ");
for (const cookie of cookies) {
const [key, value] = cookie.split("=");
if (key === TOKEN_KEY) return value;
}
return null;
};
// 移除 Token
export const removeToken = () => {
document.cookie = `${TOKEN_KEY}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
};
使用 js-cookie(推荐)
安装 js-cookie
npm install js-cookie
封装 Token 操作
import Cookies from "js-cookie";
const TOKEN_KEY = "access_token";
// 设置 Token,带过期时间(7 天)
export const setToken = (token: string) => {
Cookies.set(TOKEN_KEY, token, { expires: 7, path: "/" });
};
// 获取 Token
export const getToken = () => Cookies.get(TOKEN_KEY);
// 移除 Token
export const removeToken = () => Cookies.remove(TOKEN_KEY);
localStorage vs. Cookies
存储方式
是否支持 HttpOnly
是否支持跨域
适用场景
localStorage
❌ 不支持
❌ 仅限同源
仅前端可访问,适合存非敏感信息
Cookies
✅ 可设置 HttpOnly
✅ 可跨子域
适用于 Token 存储,安全性更高
如果后端启用了 HttpOnly,则前端无法直接获取 document.cookie,需要改用后端验证 Cookie。
5. 请求拦截器自动携带 Token在 request.ts(封装的 Axios 里),请求时自动添加 Authorization 头:
service.interceptors.request.use(
(config) => {
const token = getToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
7. Vue 全局管理用户登录状态(1) 使用 Pinia 管理 Tokenimport { defineStore } from "pinia";
import { getToken, setToken, removeToken } from "@/utils/auth";
export const useAuthStore = defineStore("auth", {
state: () => ({
token: getToken() || "",
}),
actions: {
setToken(token: string) {
this.token = token;
setToken(token);
},
logout() {
this.token = "";
removeToken();
},
},
});
(2) 在组件中使用import { useAuthStore } from "@/store/auth";
const authStore = useAuthStore();
if (!authStore.token) {
console.log("用户未登录");
}
\8. 权限控制
9. 退出登录(1) 清除 Tokenconst handleLogout = () => {
authStore.logout();
router.push("/login");
};