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

Vue Router点击后刷新页面而非跳转:两段代码差异排查

问题描述

点击结算按钮时,可成功获取后端返回的有效Stripe跳转URL,但页面仅刷新,无法跳转到目标地址。此前有可用代码版本,复制到当前项目后失效,重构后问题依旧。以下是正常运行代码与异常代码,请求分析差异、问题原因及修复方案。


可正常运行代码

前端代码

<script setup>
import { ref, onBeforeMount } from "vue";
import CheckoutSummary from "../components/CheckoutSummary.vue";
import CheckoutButton from "../components/CheckoutButton.vue";

// 响应式数据
const isLoading = ref(false);
const cart = ref([]);

// 获取购物车数据
onBeforeMount(async () => {
  const response = await fetch("/api/shopping-cart").then((r) => r.json());
  cart.value = response.cart;
});

// 按钮点击事件处理
const redirectToStripe = async () => {
  isLoading.value = true;

  const response = await fetch("/api/create-checkout-session", {
    method: "POST",
  });
  const { url } = await response.json();

  window.location.href = url;
};
</script>

后端代码

// 创建结算会话
app.post("/create-checkout-session", async (req, res) => {
  // 提取Stripe价格ID和数量,生成数组
  const lineItems = USER_SHOPPING_CART.map((item) => {
    return {
      price: item.stripePriceId,
      quantity: item.quantity,
    };
  });

  const session = await stripe.checkout.sessions.create({
    mode: "payment",
    line_items: lineItems,
    success_url: `http://localhost:3000/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `http://localhost:3000/`,
  });
  return res.send({ url: session.url });
});

异常代码

前端代码

<script setup>
import { computed } from "vue";
import { useRouter } from "vue-router";
import { useStore } from "vuex";

const router = useRouter();

// eslint-disable-next-line no-unused-vars, no-undef
const props = defineProps({
  isLoading: Boolean,
});

const store = useStore();
const cartItems = computed(() => store.getters.getCheckout);

const redirectToStripe = async () => {
  const { url } = await fetch("http://localhost:5000/create-checkout-session", {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
    },
    body: JSON.stringify(cartItems.value),
  }).then((response) => response.json());

  console.log("url=", url);
  router.go(url);
};
</script>

后端代码

app.post("/create-checkout-session", async (req, res) => {
  // 提取Stripe价格ID和数量,生成数组
  const lineItems = req.body.map((item) => {
    console.log("lineItems= ", item.item.priceId, item.item.quantity);
    return {
      price: item.item.priceId,
      quantity: item.item.quantity,
    };
  });

  const session = await stripe.checkout.sessions.create({
    mode: "payment",
    line_items: lineItems,
    success_url: `http://localhost:8080/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `http://localhost:8080/`,
  });
  return res.send({ url: session.url });
});

差异分析与问题原因

1. 前端跳转逻辑错误(核心问题)

正常代码使用window.location.href = url;直接触发浏览器原生跳转,适用于外部域名(如Stripe结算页);异常代码使用router.go(url),但**router.go()的参数是跳转步数(如+1前进、-1后退),并非URL**。传入URL会被解析为NaN,等同于调用router.go(0),即刷新当前页面,这就是跳转失效的直接原因。

2. 购物车数据传递与解析差异

  • 正常代码后端直接使用全局变量USER_SHOPPING_CART生成结算项;异常代码通过POST请求体传递Vuex中的购物车数据,后端从req.body读取。
  • 异常代码后端解析req.body时使用item.item.priceId,需确认Vuex返回的购物车数据是否为嵌套item对象的结构。若结构不匹配,会生成无效的结算项,虽当前能拿到URL,但Stripe页面可能显示购物车为空。

3. 请求路径与跨域配置

异常代码前端使用硬编码的完整域名http://localhost:5000,正常代码用相对路径。虽当前能获取URL说明跨域配置无问题,但硬编码域名不利于后续部署。


修复方案

1. 修正前端跳转逻辑

将router.go(url)替换为原生跳转方式,二选一即可:

// 方案1:最可靠的外部跳转方式
window.location.href = url;

// 方案2:Vue Router支持外部URL跳转(需确保url是完整http/https地址)
router.push(url);

2. 验证并修正购物车数据结构

检查Vuex中getCheckout返回的数据结构:

  • 若数据结构为[{ priceId: 'xxx', quantity: 1 }],需修改后端代码:
const lineItems = req.body.map((item) => {
  return {
    price: item.priceId,
    quantity: item.quantity,
  };
});
  • 若数据确实是嵌套item对象的结构,则无需修改后端,但需确保数据传递无遗漏。

3. 可选:统一请求路径(避免硬编码)

在Vue项目配置文件中设置代理(以Vite为例):

// vite.config.js
export default {
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:5000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  }
}

然后将前端请求改为相对路径:

fetch("/api/create-checkout-session", { /* ... */ })

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 04:15:38