You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止用户修改URL编辑过往答题内容 求适配Vue3+TS的解决方案

答题场景防止用户通过修改URL参数跳转过往题目的解决方案

首先明确前提:浏览器没有开放禁止用户修改地址栏的API,完全从前端限制用户操作URL无法实现,正确的思路是从「即使用户改了URL,也无法访问未授权题目」的角度做校验。


必做方案:后端校验(根源解决问题)

  • 为每个正在答题的用户生成唯一的答题会话ID,存储在服务端(Session/Redis均可),实时记录用户当前已答到的最新题号
  • 前端请求题目内容时,除了题目ID参数,额外携带答题会话ID,后端先校验会话对应的当前进度:如果请求的题目ID小于当前已到进度,直接拒绝返回题目内容,返回错误提示「已答题目不允许修改」
  • 该方案完全不受前端操作影响,就算用户篡改URL、抓包改请求参数也无法绕过。

适配Vue3+TS的前端配套方案(优化体验)

1. 路由守卫全局拦截

配合Vue Router 4做路由前置校验,用户跳转到未授权题目时自动切回当前可答题:

// router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import { useAnswerStore } from '@/store/answer' // 基于Pinia的答题状态管理

const routes: RouteRecordRaw[] = [
  {
    path: '/question',
    name: 'Question',
    component: () => import('@/views/Question.vue')
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

router.beforeEach(async (to, from, next) => {
  if (to.name === 'Question') {
    const answerStore = useAnswerStore()
    // 从后端拉取当前用户最新的可答题ID
    await answerStore.fetchCurrentAllowedQid()
    const reqQid = Number(to.query.id)
    const allowedQid = answerStore.currentAllowedQid

    // 禁止跳转到已答/未解锁的题目
    if (reqQid < allowedQid || reqQid > allowedQid) {
      return next({ path: '/question', query: { id: allowedQid } })
    }
  }
  next()
})

export default router

2. 题目ID移除出URL(可选,彻底避免用户改参数)

如果没有题目分享需求,可以直接把当前题目ID存在Pinia全局状态里,URL固定为/question不携带ID参数,用户看不到自然无法修改:

  • 切换题目时只更新全局状态的题目ID,请求后端拉取对应题目内容,URL全程无变化
  • 就算用户刷新页面,后端直接返回当前会话对应的最新题目ID,前端渲染即可,无需依赖URL参数

3. URL变化监听(临时补充方案)

如果暂时无法调整后端逻辑,可以临时用前端监听逻辑做拦截(仅能防普通用户,必须配合后端校验才安全):

// 答题页面setup逻辑
import { onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { useAnswerStore } from '@/store/answer'

const router = useRouter()
const answerStore = useAnswerStore()
// 记录当前允许的最大题号
const allowedQid = answerStore.currentAllowedQid

const checkUrlValid = () => {
  const currentQid = Number(new URLSearchParams(window.location.search).get('id'))
  if (currentQid < allowedQid) {
    // 强制切回当前可答题
    router.replace({ query: { id: allowedQid } })
    alert('已完成的题目不允许修改')
  }
}

onMounted(() => {
  // 监听浏览器前进后退操作
  window.addEventListener('popstate', checkUrlValid)
  // 监听路由切换
  const unWatchRoute = router.afterEach(checkUrlValid)

  onUnmounted(() => {
    window.removeEventListener('popstate', checkUrlValid)
    unWatchRoute()
  })
})

重要提示:所有前端拦截逻辑都只能做体验优化,无法作为安全校验,懂技术的用户可以通过禁用JS、抓包改请求等方式绕过,必须搭配后端校验使用。


内容的提问来源于stack exchange,提问作者Cena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 10:24:03