在Rails 8中结合Inertia.js实现redirect_to跳转的方案咨询
Rails 8 + Inertia.js + Vue 实现控制器内重定向跳转解决方案
问题根源
你之前用axios发送普通POST请求,而非Inertia官方的请求方式,导致后端返回的Inertia重定向响应无法被前端识别处理。只有Inertia发起的请求才会自动解析后端的重定向指令。
解决方案步骤
1. 前端替换请求方式(改用Inertia Router)
修改/app/frontend/pages/Store/Index.vue中的请求逻辑,移除axios,使用Inertia自带的router.post方法,它会自动处理CSRF令牌和Inertia请求标识:
<template> <button @click="addToCart(product.id)" class="ml-4 rounded-lg py-1 px-2 text-white bg-green-600" > Add to Cart </button> </template> <script setup lang="ts"> import { router } from '@inertiajs/vue3'; const addToCart = async (productId: number) => { try { await router.post('/line_items', { product_id: productId }, { onSuccess: () => { alert('Product added to cart!'); }, onError: (errors) => { console.error('Error adding to cart: ', errors); alert('Failed to add product to cart.'); } }); } catch (error) { console.error('Error adding to cart: ', error); alert('Failed to add product to cart.'); } }; </script>
2. 后端调整重定向代码
修改/app/controllers/line_items_controller.rb的create方法,使用skryukov/inertia_rails-contrib的redirect_to inertia:语法,同时可以传递通知消息:
def create product = Product.find(params[:product_id]) @line_item = @cart.line_items.build(product: product) if @line_item.save redirect_to inertia: cart_path(@cart), notice: "商品已成功加入购物车" else redirect_to inertia: store_index_path, errors: @line_item.errors.full_messages end end
3. 可选:前端接收通知消息
如果需要在前端显示后端传递的notice,可以在Rails布局中配置flash传递:
# app/views/layouts/application.html.erb <%= inertia_page_tag( props: { flash: { notice: notice, alert: alert } } ) %>
然后在Vue页面中获取使用:
<script setup lang="ts"> import { usePage } from '@inertiajs/vue3'; const page = usePage(); if (page.props.flash.notice) { alert(page.props.flash.notice); } </script>
关键说明
- Inertia的重定向仅对Inertia发起的请求生效(即通过
router.get/post/put/delete等方法发送的请求),普通axios/fetch请求无法识别Inertia的重定向响应。 skryukov/inertia_rails-contrib的redirect_to inertia:语法会自动生成符合Inertia规范的重定向响应,包含X-Inertia-Location头,前端Inertia Router会自动处理该头完成跳转。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

