要在页面上验证内容是否在服务器端渲染,你可以通过以下几种方式:
1、查看页面源代码(View Page Source):
- 在浏览器中右键点击页面,选择"查看网页源代码"(View Page Source)
- 或者使用快捷键 Ctrl + U(Windows)/ Cmd + U(Mac)
- 在源代码中,你应该能看到完整的 HTML 内容,包括用户数据,类似这样:
而如果是客户端则没有用户数据,只有 html 代码
2、禁用 JavaScript:
禁用快捷路径: chrome://settings/content/javascript
添加网址, 刷新页面,如果内容仍然显示,说明是服务器端渲染的
3、使用网络慢速模式:
- 在 Chrome 开发者工具中
- 切换到 "Network" 标签
- 在 "throttling" 下拉菜单中选择 "Slow 3G"
- 刷新页面,你会看到内容是立即显示的,而不是等待 JavaScript 加载后才显示
4、使用 curl 命令(终端)
curl http://localhost:3000/about
这将显示服务器返回的原始 HTML,如果看到用户数据在 HTML 中,就证明是服务器端渲染的。
如果是客户端渲染,你在页面源代码中只能看到基本的 HTML 结构,不会包含用户数据,数据会在 JavaScript 执行后才显示出来。而服务器端渲染的内容会直接出现在初始 HTML 中。
demo 示例
// 客户端代码demo
"use client"
import { useState, useEffect } from 'react';
function getUsers() {
return fetch('https://jsonplaceholder.typicode.com/users')
.then(res => {
if (!res.ok) {
throw new Error('Failed to fetch users');
}
return res.json();
});
}
export default function About() {
const [users, setUsers] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
getUsers()
.then(data => {
setUsers(data);
setLoading(false);
})
.catch(err => {
setError(err.message);
setLoading(false);
});
}, []);
if (loading) {
return <div className="p-4">Loading...</div>;
}
if (error) {
return <div className="p-4 text-red-500">Error: {error}</div>;
}
return (
<div className="p-4">
<h1 className="text-2xl font-bold mb-4">关于我们的团队(客户端)</h1>
<div className="grid gap-4">
{users.map((user: any) => (
<div key={user.id} className="border p-4 rounded-lg">
<h2 className="text-xl font-semibold">{user.name}</h2>
<p className="text-gray-600">{user.email}</p>
<p className="text-gray-600">{user.company.name}</p>
</div>
))}
</div>
</div>
);
}
// 服务端代码
async function getUsers() {
console.log('Fetching users from server side...'); // 这个只会在服务器端控制台显示
const res = await fetch('https://jsonplaceholder.typicode.com/users', {
// 强制 SSR
cache: 'no-store'
});
if (!res.ok) {
throw new Error('Failed to fetch users');
}
return res.json();
}
export default async function About() {
const users = await getUsers();
return (
<div className="p-4">
<h1 className="text-2xl font-bold mb-4">关于我们的团队(服务端)</h1>
<div className="grid gap-4">
{users.map((user: any) => (
<div key={user.id} className="border p-4 rounded-lg">
<h2 className="text-xl font-semibold">{user.name}</h2>
<p className="text-gray-600">{user.email}</p>
<p className="text-gray-600">{user.company.name}</p>
</div>
))}
</div>
</div>
);
}
注意事项
-
hydration 的影响:Next.js 的客户端组件通常通过 hydration 与服务端生成的 HTML 结合。即使是客户端组件,如果页面使用了 SSR 或 SSG,源代码中可能仍有初始内容。
-
构建模式:
- SSG(静态生成) :所有组件(包括客户端组件的初始状态)可能在构建时生成,禁用 JS 也能看到内容。
- SSR(服务端渲染) :内容动态生成,服务端组件占主导。
-
动态导入:如果客户端组件通过 dynamic 导入,禁用 JS 可能导致完全不可见。
亲测这四种方式都可以,这不我就发现自己 用 Next.js 写的博客网站不是 ssr 渲染...