jeecgboot/JeecgBoot · error · Error

token不存在~

Error message

token不存在~

What it means

Setup guard in the URL-style online Add form. `useFormUrl()` resolves the token from `route.query.token`, falling back to `userStore.getToken`; if neither is present it schedules an async demo-token fetch + page reload. The synchronous `if (!unref(token))` throw fires immediately when token is still falsy, halting render because every online form API call needs a bearer token.

Source

Thrown at jeecgboot-vue3/src/views/super/online/cgform/auto/default/OnlineFormUrlAdd.vue:45

  // OnlineForm 这个必须引用,setup模式必须在template里面使用。否则url进入会报错
  import OnlineForm from '../comp/OnlineForm.vue';
  import { useMessage } from '/@/hooks/web/useMessage';
  import OnlineAutoModal from './OnlineAutoModal.vue';
  import { useOnlineTableContext } from '../../hooks/auto/useOnlineTableContext';
  import { useListButton } from '../../hooks/auto/useListButton';
  import { useEnhance } from '../../hooks/auto/useEnhance';
  import { useRouter } from 'vue-router';
  import { useFormUrl } from '../../hooks/auto/useFormUrl';
  const { ID, onlineTableContext, onlineExtConfigJson, handleFormConfig } = useOnlineTableContext();
  const { createMessage: $message } = useMessage();
  const wrapRef = ref(null);
  const contentHeight = ref(400);
  const loading = ref(true);
  const router = useRouter();

  const { token } = useFormUrl();
  if (!unref(token)) {
    throw new Error('token不存在~');
  }
  if (!ID.value) {
    $message.warning('地址错误, 配置ID不存在!');
    throw new Error('地址错误, 配置ID不存在!');
  }
  // 处理增强
  let { initCgEnhanceJs } = useEnhance(onlineTableContext);
  watch(
    () => wrapRef.value,
    (elem: HTMLElement) => {
      // 获取页面实际高度
      contentHeight.value = elem.offsetHeight - 60;
    }
  );
  // 处理列表button
  const { registerModal, handleAdd } = useListButton(onlineTableContext, onlineExtConfigJson);
  const getContainer = (node) => {
    return document.querySelector(`.online-add-${ID.value}`);

View on GitHub (pinned to 96fb33f5ec)

Solutions

  1. Log in to the platform first, then reopen the form so `userStore.getToken` populates `token`.
  2. Append a valid `?token=<jwt>` to the URL for external/embedded use.
  3. Ensure the SSO/login flow completes and sets the token before the form route mounts.
  4. For external embedding, generate a long-lived form token server-side and pass it in the URL.

Example fix

// before
const { token } = useFormUrl();
if (!unref(token)) { throw new Error('token不存在~'); }

// after — redirect to login (or back with the return url) instead of a hard throw
const { token } = useFormUrl();
if (!unref(token)) {
  router.replace({ path: '/user/login', query: { redirect: route.fullPath } });
  return;
}
Defensive patterns

Strategy: validation

Validate before calling

// confirm token presence before relying on it
const { token } = useFormUrl();
if (!unref(token)) {
  router.replace({ path: '/user/login', query: { redirect: route.fullPath } });
  return;
}

Type guard

const hasToken = (t: unknown): t is string => typeof t === 'string' && t.length > 0;

Prevention

When it happens

Trigger: Opening the form URL without a `?token=` query param while NOT logged in (so `userStore.getToken` is also empty). The companion async token fetch hasn't run yet, so the synchronous guard throws first.

Common situations: Sharing the form link externally without appending `?token=...`; session expired and token cleared; opening in an incognito/private window; an SSO/login redirect loop left the user store empty.

Related errors


AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14). Data as JSON: /api/errors/e7e9a7e369dff069. Report an issue: GitHub.