请求状态码
HTTP 301 Moved Permanently
说明请求的资源已经被移动到了由 Location 头部指定的 url 上,是固定的不会再改变。
HTTP 302 Found
重定向状态码表明请求的资源被暂时的移动到了由该 HTTP 响应的响应头 Location 指定的 URL 上。
服务端重定向
一开始认为后端通过设置 302 状态码及 location 后,前端页面就会自动跳转至 location 页面。多次尝试无果后去请教小助理,回复如下:
于是调整了思路,实现了小助理说的两种方案。如下:
a 标签跳转
<template>
<a href="http://localhost:3000/redirect?redirect_url=/about">
点击a标签时重定向至about页面
</a>
</template>
JavaScript 手动跳转
<template>about</template>
<script setup>
import axios from "axios";
axios
.get("http://localhost:3000/redirect", {
params: {
redirect_url: "/detail",
},
})
.then((res) => {
// 这里相当于是获取重定向之后的请求
window.location = res.request.responseURL;
});
</script>
服务端代码
const Koa = require("koa");
const Router = require("koa-router");
const cors = require("@koa/cors");
const app = new Koa();
const router = new Router();
app.use(cors({ origin: "*" }));
router.get("/redirect", async (ctx, next) => {
const { redirect_url } = ctx.request.query;
ctx.status = 301;
ctx.set("Location", "http://localhost:5173" + redirect_url); // 设置重定向的目标 URL
});
app.use(router.routes());
app.use(router.allowedMethods());
// 监听3000端口
app.listen(3000, () => {
console.log("Server is running at http://localhost:3000");
});
写完后总感觉很变扭。
新开标签认证
即从登录页点击数字证书登录,打开新标签页进行认证。认证成功后,新标签页关闭,登录页跳转至首页。
- 登录页如下
<template>
<button @click="openBPage">数字证书认证</button>
</template>
<script setup>
let bWindow = null;
const openBPage = () => {
bWindow = window.open("/certificate?userId=123", "_blank");
};
const ws = new WebSocket("ws://localhost:3000?userId=123");
ws.onopen = (event) => {
ws.send("Hello, server!");
};
ws.onmessage = function (event) {
if (event.data === "认证成功") {
// 关闭 B 标签页
bWindow.close();
// A 标签页跳转至首页
window.location.href = "http://localhost:5173";
}
};
ws.onclose = (event) => {
console.log("连接关闭");
};
ws.onerror = (event) => {
console.error("连接发生错误:", event);
};
</script>
- 认证标签页
<template>
<p>数字证书认证页</p>
</template>
<script setup>
import axios from "axios";
import { useRoute } from "vue-router";
const route = useRoute();
const userId = route.query.userId;
axios
.post("http://localhost:3000/auth", {
userId,
})
.then((res) => {
console.log(res.data);
})
.catch((error) => {
console.log(error);
});
</script>
- 对应服务端代码
const Koa = require("koa");
const Router = require("koa-router");
const cors = require("@koa/cors");
const WebSocket = require("ws");
const http = require("http");
const bodyParser = require("koa-bodyparser");
const app = new Koa();
const router = new Router();
const sockets = {}; // 将 sockets 对象设置为全局变量
app.use(cors({ origin: "*" }));
app.use(bodyParser()); // 使用 koa-bodyparser 中间件
router.post("/auth", (ctx, next) => {
const { userId } = ctx.request.body;
sockets[userId].send("认证成功");
ctx.body = {
code: 0,
msg: "认证成功",
};
});
app.use(router.routes());
app.use(router.allowedMethods());
// 创建一个原生的HTTP服务器来处理Koa应用和WebSocket
const server = http.createServer(app.callback());
const wss = new WebSocket.Server({ server });
wss.on("connection", (ws, request) => {
let userId = new URL(request.url, "ws://localhost:3000").searchParams.get(
"userId"
);
sockets[userId] = ws;
ws.send("连接成功");
ws.on("message", (message) => {
console.log("received: %s", message);
});
});
// 监听3000端口
server.listen(3000, () => {
console.log("Server is running at http://localhost:3000");
});