2026-04-29 12:24:44 +08:00
|
|
|
//! SSR (Server-Side Rendering) 模块
|
|
|
|
|
//!
|
|
|
|
|
//! 提供 Leptos 0.8 的 SSR 渲染基础设施。
|
|
|
|
|
//! 使用 `RenderHtml::to_html_with_buf` 将 Leptos view 渲染为 HTML 字符串。
|
|
|
|
|
|
|
|
|
|
pub mod pages;
|
|
|
|
|
pub mod styles;
|
|
|
|
|
|
|
|
|
|
pub use styles::MNOTE_CSS;
|
|
|
|
|
|
|
|
|
|
use leptos::prelude::*;
|
|
|
|
|
use leptos::tachys::view::Position;
|
|
|
|
|
|
|
|
|
|
/// 将任何实现 `RenderHtml` 的视图渲染为 HTML 字符串 (SSR)
|
|
|
|
|
///
|
|
|
|
|
/// 使用 Leptos 0.8 的 `RenderHtml::to_html_with_buf` 方法,
|
|
|
|
|
/// 通过 `Position::default()` (即 FirstChild) 初始化位置状态。
|
|
|
|
|
pub fn render_view(view: impl RenderHtml) -> String {
|
|
|
|
|
let mut buf = String::new();
|
|
|
|
|
let mut position = Position::default();
|
|
|
|
|
RenderHtml::to_html_with_buf(
|
|
|
|
|
view,
|
|
|
|
|
&mut buf,
|
|
|
|
|
&mut position,
|
2026-04-29 14:36:24 +08:00
|
|
|
true, // escape — 对 HTML 特殊字符进行转义
|
|
|
|
|
false, // mark_branches — 不标记分支注释
|
2026-04-29 12:24:44 +08:00
|
|
|
vec![], // extra_attrs — 无需额外属性
|
|
|
|
|
);
|
|
|
|
|
buf
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use super::*;
|
|
|
|
|
use leptos::view;
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn render_view_produces_non_empty_html() {
|
|
|
|
|
let html = render_view(view! { <h1>"Hello SSR"</h1> });
|
|
|
|
|
assert!(!html.is_empty());
|
|
|
|
|
assert!(html.contains("Hello SSR"));
|
|
|
|
|
assert!(html.contains("<h1>"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn render_view_escapes_html_special_chars() {
|
|
|
|
|
let html = render_view(view! { <p>"<script>alert('xss')</script>"</p> });
|
|
|
|
|
assert!(html.contains("<"));
|
|
|
|
|
assert!(!html.contains("<script>"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn render_view_renders_nested_elements() {
|
|
|
|
|
let html = render_view(view! {
|
|
|
|
|
<main>
|
|
|
|
|
<header><h1>"Title"</h1></header>
|
|
|
|
|
<section><p>"Content"</p></section>
|
|
|
|
|
</main>
|
|
|
|
|
});
|
|
|
|
|
assert!(html.contains("<main>"));
|
|
|
|
|
assert!(html.contains("<header>"));
|
|
|
|
|
assert!(html.contains("<h1>Title</h1>"));
|
|
|
|
|
assert!(html.contains("<section>"));
|
|
|
|
|
assert!(html.contains("<p>Content</p>"));
|
|
|
|
|
}
|
|
|
|
|
}
|