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

Rails作为API、Vite为前端服务时Vue前端无法渲染求助

解决Rails API + Vue + Vite 前后端无法连接、前端不渲染问题

核心问题

你的Rails应用是API模式,默认不会返回HTML视图;同时前端Vite服务和Rails后端没有正确的路由衔接,导致访问时直接返回API的JSON数据,而非前端页面。


具体修复步骤

1. 创建静态页面控制器

Rails API模式缺少返回HTML的控制器,需新增StaticController来返回前端的index.html:

rails generate controller Static index --skip-assets --skip-helper --skip-template-engine

修改app/controllers/static_controller.rb,让它继承ActionController::Base(而非API)以支持HTML渲染:

class StaticController < ActionController::Base
  def index
    render file: Rails.root.join('app/frontend/index.html'), layout: false
  end
end

2. 调整Rails中间件配置

API模式会移除处理静态文件和HTML的中间件,打开config/application.rb,在现有配置中添加:

# 在config.api_only = true前后添加均可
config.middleware.use ActionDispatch::Static
config.middleware.use Rack::Sendfile

3. 修正路由优先级

让所有非API的HTML请求都返回前端页面,修改config/routes.rb:

# 替换原root路由
root 'static#index'

# API路由放在最前面
namespace :api do
  namespace :v1 do
    resources :chatrooms, only: %i[index] do
      resources :messages, only: %i[index create]
    end
  end
end

devise_for :users,
      controllers: {
          sessions: "users/sessions",
          registrations: "users/registrations"
      }

resources :tracks
resources :instruments, only: [:index, :new, :create]
resources :genres, only: [:index, :new, :create]

get '/index_results/:id', to: 'tracks#index_results', as: 'index_results'
get '/my_tracks', to: 'tracks#myTracks', as: 'myTracks'
get "/member-data", to: "members#show"

# 兜底路由,确保所有HTML请求都返回前端页面
get "*path", to: "static#index", constraints: proc { |request| !request.xhr? && request.format.html? }

4. 修复Vite资源路径

在app/frontend/index.html中,修改script标签指向Vite开发服务的绝对路径:

<script type="module" src="http://localhost:3036/entrypoints/application.js"></script>

同时在Rails中配置内容安全策略,允许Vite资源加载,创建或修改config/initializers/content_security_policy.rb:

Rails.application.config.content_security_policy do |policy|
  if Rails.env.development?
    policy.connect_src :self, :https, 'http://localhost:3036'
    policy.script_src :self, :https, 'http://localhost:3036', :unsafe_eval, :unsafe_inline
    policy.style_src :self, :https, 'http://localhost:3036', :unsafe_inline
  end
end

5. 修复Vue Router的Store初始化问题

router.js中的authGuard直接调用useSessionStore()时,Pinia还未完成初始化,会导致Vue无法挂载。修改router.js:

// 导入并创建Pinia实例
import { createPinia } from 'pinia'
const pinia = createPinia()

// 修改authGuard逻辑
const authGuard = (to, _from, next) => {
  const sessionStore = useSessionStore(pinia)
  const isLoggedIn = sessionStore.isLoggedIn
  const requiresAuth = to.meta.requiresAuth

  if (isLoggedIn && !requiresAuth) return next({ name: "Home" })
  if (!isLoggedIn && requiresAuth) return next({ name: "Login" })

  return next()
}

6. 正确启动服务

  1. 第一个终端启动Vite:vite dev
  2. 第二个终端启动Rails:rails s
  3. 访问http://localhost:3000,前端页面应该正常渲染

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:56:05