php可以抓取网页数据吗(.js与前端React无缝对接之一下三种渲染方式 )
优采云 发布时间: 2021-10-11 14:13php可以抓取网页数据吗(.js与前端React无缝对接之一下三种渲染方式
)
Next.js 是一个轻量级的 React 服务器端渲染框架
它支持三种渲染方法,包括
旧瓶装新酒
上面提到的几种渲染方式其实并不新鲜,但是可以对应这些技术。
区别
Next.js的预渲染可以和前端React无缝对接
下面以一个文章列表页面为例,分别分析三种渲染方式。
客户端渲染
顾名思义,客户端渲染是仅在浏览器上执行的渲染。通过Vue和React构建的单页应用SPA都是这样渲染的
缺点
1.白屏,AJAX渲染前页面没有内容,只能通过Loading覆盖
2. SEO不友好,因为搜索引擎访问页面,默认不会执行JS,而是只能看到HTML而不是等待AJAX异步请求数据,所以无法搜索到页面内容
代码
import {NextPage} from 'next';
import axios from 'axios';
import {useEffect, useState} from "react";
import * as React from "react";
type Post = {
id: string,
id: string,
title: string
}
const PostsIndex: NextPage = () => {
// [] 表示只在第一次渲染的时候请求
const [posts, setPosts] = useState([]);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
setIsLoading(true);
// 使用 AJAX 异步请求数据
axios.get('/api/posts').then(response => {
setPosts(response.data);
setIsLoading(false);
}, () => {
setIsLoading(true);
})
}, []);
return (
文章列表
{isLoading ? 加载中 :
posts.map(p =>
{p.id}
)}
)
};
export default PostsIndex;
网络不好的时候,加载时间很长,很长一段时间页面可能会出现空白。
由于第一次请求的HTML中没有文章内容,需要通过AJAX异步加载数据,加载数据渲染的过程在客户端完成,所以称为客户端渲染
静态页面生成 SSG
在文章列表页面,其实每个用户找到的内容都是一样的
那为什么还要在大家的浏览器上渲染呢?
为什么不在后台渲染出来发给大家
好的
N个渲染变成了1个渲染
N个客户端渲染变成了1个静态页面生成
这个过程变成了动态内容的静态
利弊
优点:这个方法可以解决白屏问题和SEO问题
缺点:所有用户看到的都是同一个页面,无法生成用户相关的内容
如何实现
首先让我们思考一个问题
如何获取帖子?因为加载数据的操作在后端,通过AJAX获取帖子显然是不合适的
答案是:通过getStaticProps获取帖子
getStaticProps是Next.js提供的一个方法,会在后端执行,返回一个prop,供NextPage渲染时使用
代码
import {GetStaticProps, NextPage} from 'next';
import {getPosts} from '../../lib/posts';
import Link from 'next/link';
import * as React from 'react';
type Post = {
id: string,
title: string
}
type Props = {
posts: Post[];
}
// props 中有下面导出的数据 posts
const PostsIndex: NextPage = (props) => {
const {posts} = props;
// 前后端控制台都能打印 -> 同构
console.log(posts);
return (
文章列表
{posts.map(p =>
{p.id}
)}
);
};
export default PostsIndex;
// 实现SSG
export const getStaticProps: GetStaticProps = async () => {
const posts = await getPosts();
return {
props: {
posts: JSON.parse(JSON.stringify(posts))
}
};
};
前端不通过ajax获取数据怎么办
我们只拿到了服务器上的posts数据,但是怎么传到前端呢?
发现奥秘
我们可以看到隐藏在id为_NEXT_DATA__的script标签中,里面存放的是传递给前端的props数据
这就是同构SSR的好处,后端可以直接把数据传给前端,不需要AJAX异步获取
静态时序环境在开发环境中。GetStaticProps 将为每个请求运行一次。这是为了方便您修改代码并在构建环境中重新运行。GetStaticProps 只在构建中运行一次,可以提供一份 HTML 副本供所有用户下载
如何体验构建环境
yarn build
yarn start
打包后,我们可以看到这个
解释
我看到的页面前面的三个图标是λ ○ ●
λ (Serve) SSR 无法自动创建 HTML(如下所述)
○(静态)自动创建HTML(发现你没用props)
●(SSG)自动创建HTML + JSON(等你使用道具)
三种文件类型
构建完成后,我们查看.next文件,找到posts.html、posts.js、posts.json
为什么不直接将数据放入posts.js?
很明显,posts.js 是为了接受不同的数据。当我们展示每个博客时,它们的风格相同,内容不同,所以会用到这个功能
动态内容静态
服务器端渲染 (SSR)
如果页面与用户相关怎么办?
这种情况更难以提前静止。需要在用户请求的时候获取用户信息,然后利用用户信息从数据库中获取数据。如果必须这样做,则必须为每个用户创建一个页面。有时数据更新得非常快。, 不能提前静态,比如微博首页的信息流
那该怎么办呢?
无论是客户端渲染,都会出现白屏
要么服务端渲染SSR,没有白屏
运行
不管是开发环境还是构建环境,getServerSideProps都是在请求之后运行的
代码
与 SSG 代码基本相同,但使用 getSeverSideProps
这段代码执行时,服务器响应请求后获取浏览器信息,返回给前端显示
import {GetServerSideProps, NextPage} from 'next';
import * as React from 'react';
import {IncomingHttpHeaders} from 'http';
type Props = {
browser: string
}
const index: NextPage = (props) => {
return (
你的浏览器是 {props.browser}
);
};
export default index;
export const getServerSideProps: GetServerSideProps = async (context) => {
const headers:IncomingHttpHeaders = context.req.headers;
const browser = headers['user-agent'];
return {
props: {
browser
}
};
};
SSR原理
建议后端使用 renderToString(),前端使用 hydrate()
后端渲染页面,返回 HTML String 格式,并传递给前端。前端执行 hydrate(),保留 HTML 并附加时间监控,即后端渲染 HTML,前端添加监控。
前端也会渲染一次,保证前后渲染结果一致
总结客户端渲染SSR
只在浏览器上运行,缺点SEO不友好,白屏
静态页面生成 SSG
静态站点生成,解决白屏问题和SEO问题
缺点:无法生成用户相关内容(所有用户请求的结果都一样)
服务器端渲染 (SSR)
解决白屏问题,SEO问题
可以生成用户相关的内容
如何选择三种渲染模式