Svelte+Spring Boot实现无URL暴露ID的页面跳转方法咨询
问题
我正在用Svelte和Spring Boot开发找回ID页面,流程是:
- 用户在找回ID页面输入账户信息;
- 点击确认按钮校验账户是否存在;
- 校验匹配时跳转至ID结果页面并传递ID值。
目前用URL参数传递ID的方式跳转,代码如下:
goto('/login/viewId?loginId=${loginId}`)
我自己写的逻辑代码:
async function findId() { const formData = new FormData(document.getElementById('Form')); const response = await Api.post(`/login/IdCheck`, formData); // 1. ID校验 if (response.data.resultCode == 'success') { var loginId = response.data.findInfo.loginId; goto(`./Id/IdDisplay?Id=${Id}`);// 这里用Query String会暴露ID,不想这么做 } }
现在想实现跳转时不把ID暴露在URL里,问是否需要通过Controller重定向?
解决方案
不需要非得用Controller重定向,有几种更实用的方案:
1. Svelte端用全局状态存储ID
利用Svelte内置的store做全局状态管理,把获取到的ID存在状态里,跳转后直接从状态读取,全程不会碰URL:
操作步骤:
- 先创建一个全局store文件(比如
src/stores/userStore.js):
import { writable } from 'svelte/store'; export const recoveredLoginId = writable(null);
- 在找回ID页面组件里导入并更新store:
import { recoveredLoginId } from '../stores/userStore.js'; async function findId() { const formData = new FormData(document.getElementById('Form')); const response = await Api.post(`/login/IdCheck`, formData); if (response.data.resultCode == 'success') { const loginId = response.data.findInfo.loginId; $recoveredLoginId = loginId; // 把ID存入全局状态 goto('./Id/IdDisplay'); // 不带任何参数跳转 } }
- 在ID结果页面(IdDisplay)直接读取store值:
import { recoveredLoginId } from '../stores/userStore.js'; // 页面里直接用$recoveredLoginId展示ID即可
这种纯前端方案简单高效,适合普通场景。
2. Spring Boot后端存会话+接口取ID
如果对安全性要求高(怕前端篡改ID),可以让后端把ID存到用户会话里,前端跳转后再通过接口从后端取:
操作步骤:
- 修改Spring Boot的
IdCheck接口,校验成功后把ID存入HttpSession:
@PostMapping("/login/IdCheck") public ResponseEntity<?> checkId(@RequestBody FormData formData, HttpSession session) { // 这里写账户校验逻辑 if (校验通过) { String loginId = 查询到的用户ID; session.setAttribute("recoveredLoginId", loginId); // 把ID存到会话 return ResponseEntity.ok(Map.of("resultCode", "success", "redirectUrl", "/login/IdDisplay")); } else { return ResponseEntity.ok(Map.of("resultCode", "fail")); } }
- 新增一个获取ID的接口:
@GetMapping("/login/getRecoveredId") public ResponseEntity<?> getRecoveredId(HttpSession session) { String loginId = (String) session.getAttribute("recoveredLoginId"); if (loginId != null) { session.removeAttribute("recoveredLoginId"); // 用完就删,避免重复获取 return ResponseEntity.ok(Map.of("loginId", loginId)); } else { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("无有效ID"); } }
- Svelte端修改跳转逻辑:
async function findId() { const formData = new FormData(document.getElementById('Form')); const response = await Api.post(`/login/IdCheck`, formData); if (response.data.resultCode == 'success') { goto(response.data.redirectUrl); // 跳转到结果页面 } }
- 在ID结果页面初始化时调用接口拿ID:
import { onMount } from 'svelte'; let loginId = ''; onMount(async () => { const response = await Api.get(`/login/getRecoveredId`); if (response.status === 200) { loginId = response.data.loginId; } });
这种方式ID只存在服务器会话中,前端全程碰不到原始ID,安全性更高。
3. POST表单跳转(不推荐)
如果一定要用跳转时传数据,也可以动态创建隐藏表单用POST提交,但这种方式会触发页面刷新,不符合Svelte单页应用的体验,仅作备选:
async function findId() { const formData = new FormData(document.getElementById('Form')); const response = await Api.post(`/login/IdCheck`, formData); if (response.data.resultCode == 'success') { const loginId = response.data.findInfo.loginId; // 创建隐藏表单 const form = document.createElement('form'); form.method = 'POST'; form.action = './Id/IdDisplay'; const input = document.createElement('input'); input.type = 'hidden'; input.name = 'loginId'; input.value = loginId; form.appendChild(input); document.body.appendChild(form); form.submit(); document.body.removeChild(form); } }
然后Spring Boot的结果页面Controller用@PostMapping接收参数即可。
内容的提问来源于stack exchange,提问作者car
相关产品推荐
相关产品推荐

