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

如何实现FastAPI与Vue 3的服务端渲染(SSR)?

FastAPI 与 Vue 3 SSR 实现方案及替代方案

一、FastAPI 实现 Vue 3 SSR 的可行方法

Vue 3 的 SSR 核心依赖 Node.js 环境执行组件渲染逻辑,FastAPI 作为 Python 框架无法直接运行 Vue 的 SSR 代码,但可以通过以下两种方式间接实现:

1. FastAPI 作为网关调用 Node.js SSR 服务

  • 先基于 Node.js 搭建独立的 Vue SSR 服务:使用 Vue 官方的 @vitejs/plugin-vue-ssr 或 Nuxt.js 构建 SSR 服务,暴露 HTTP 接口接收请求路径、动态数据,返回渲染后的完整 HTML。
  • FastAPI 端通过 httpx 等库调用该 Node 服务,将客户端请求的路径、需要注入的动态参数传递过去,拿到渲染后的 HTML 后返回给客户端。

示例代码(FastAPI 端):

from fastapi import FastAPI, Request, HTMLResponse
import httpx

app = FastAPI()
NODE_SSR_URL = "http://localhost:3000/ssr"

@app.get("/{path:path}")
async def render_ssr(request: Request, path: str):
    async with httpx.AsyncClient() as client:
        response = await client.post(NODE_SSR_URL, json={
            "path": path,
            "dynamic_data": {"user_id": request.headers.get("X-User-ID")}
        })
        html = response.text
        return HTMLResponse(content=html, status_code=200)

2. Python 调用 Node 脚本执行 SSR 渲染

对于轻量场景,可通过 Python 的 subprocess 模块调用 Node 脚本,传入请求路径和动态数据,脚本执行 Vue SSR 渲染后输出 HTML,FastAPI 捕获输出并返回。

示例代码:

from fastapi import FastAPI, HTMLResponse
import subprocess
import json

app = FastAPI()

@app.get("/{path:path}")
def render_ssr(path: str):
    params = json.dumps({"path": path, "data": {"title": "动态页面"}})
    result = subprocess.run(
        ["node", "./vue-ssr-renderer.js", params],
        capture_output=True,
        text=True
    )
    html = result.stdout
    return HTMLResponse(content=html)

二、Vue 构建产物与 Jinja2 结合的动态部署方案

如果不想依赖 Node.js SSR 服务,可以通过修改 Vue 分隔符、改造构建产物为 Jinja2 模板的方式实现动态页面,步骤如下:

1. 修改 Vue 模板分隔符

避免 Vue 的双大括号与 Jinja2 冲突,在 Vue 项目配置中修改分隔符:

  • 若使用 Vite,在 vite.config.js 中添加:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue({
    template: {
      delimiters: ['[[', ']]']
    }
  })]
})
  • 若使用 Vue CLI,在 vue.config.js 中添加:
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap(options => {
        options.compilerOptions = {
          delimiters: ['[[', ']]']
        }
        return options
      })
  }
}

2. 构建 Vue 项目并改造 index.html 为 Jinja2 模板

  • 执行 npm run build 生成 dist 目录。
  • 将 dist/index.html 移至 FastAPI 的 templates 目录,在需要动态插入数据的位置使用 Jinja2 语法,示例:
<head>
  <title>{{ page_title }}</title>
  <link rel="stylesheet" href="/assets/index.[hash].css">
</head>
<body>
  <div id="app"></div>
  <script>
    window.__INITIAL_STATE__ = {{ initial_state | tojson }}
  </script>
  <script type="module" src="/assets/index.[hash].js"></script>
</body>

3. FastAPI 配置路由与模板渲染

配置 FastAPI 加载静态文件、渲染模板,并处理 SPA 路由回退:

from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
import os

app = FastAPI()
static_folder = "./dist"
templates = Jinja2Templates(directory="./templates")

app.mount("/assets", StaticFiles(directory=f"{static_folder}/assets"), name="assets")

@app.get("/")
def render_home(request: Request):
    return templates.TemplateResponse("index.html", {
        "request": request,
        "page_title": "首页",
        "initial_state": {"username": "test_user"}
    })

@app.get("/{catchall:path}")
def render_dynamic_page(request: Request, catchall: str):
    page_data = {
        "page_title": f"{catchall} 页面",
        "initial_state": {"path": catchall}
    }
    static_file_path = os.path.join(static_folder, catchall)
    if os.path.exists(static_file_path) and os.path.isfile(static_file_path):
        return StaticFiles(directory=static_folder).get_response(catchall, request.scope)
    return templates.TemplateResponse("index.html", {
        "request": request,
        **page_data
    })

4. Vue 读取全局初始化数据

在 Vue 入口文件中读取 FastAPI 注入的动态数据:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)
app.config.globalProperties.$initialState = window.__INITIAL_STATE__
app.use(router).mount('#app')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:15:55