服务器和 db 都是 utc ,先是统一了客户端提交的时间数据,都统一用 timestamp ,又处理了服务器和客户端渲染不一致导致的 hydration 错误。
首屏上需要显示最近一周的统计数据,可是“最近一周”是跟用户时区相关的概念,没办法在 RSC 里预先获取数据,于是翻车了。 项目开始的时候我宣传了半天 RSC 的优势,有点骑虎难下,而且 RSC 和 server action 用上后开发和用户体验都好了不少。首屏实在不想退回到 useEffect 。
现在能想到的一个办法是在 middleware 里返回给用户一个脚本,把 timezone 写到 cookie 里,再重定向到首页,之后按照 cookie 做 ssr 。
本来信心满满的用上 next14 ,server action 把 API 都淘汰掉,还挺得意的。这样一个平常的问题搞了我 2 天,郁闷死了。
1
hingle 297 天前
时区是可以存放在“个人设置”里的(比如 v2 设置最后一行就有时区),这样就可以从数据库里拿了。
|
2
rocmax OP @hingle 感谢!
这个项目跟其他服务共用认证服务的,用户数据从 jwt 里直接取,加项目有点困难,本服务里存的话还得搞同步。 即使存到数据库里,服务端渲染解决了,dom 树叶子结点的客户端组件如果从顶层 RSC 层层传时区下来的话有点麻烦 直接从浏览器取时区的话又可能有不一致的问题。 |
3
caola 297 天前 via iPhone
数据统一使用 UTC ?需要显示时再转换时区?
|
4
rocmax OP @caola 现在就是这个策略,问题在于 ssr 的时候不知道客户端在哪个时区,我甚至试了获取 utc-12 到 utc+14 的所有数据,在客户端 filter 这种操作
|
5
MENGKE 297 天前
从客户端不可能拿到 100%正确的时间
|
6
rocmax OP |
7
MENGKE 297 天前
@rocmax #6 ssr 最大的目的不应该是为了 seo 和提高加载速度么,像“最近一周”这种每个用户看到的都应该是自己的和别人不一样的,我感觉完全没有做 ssr 的必要性。
|
10
rocmax OP nextjs14 开始 ssr 的优势已经不限于首屏性能和 seo ,还有 streaming 和 boundary 等等组件粒度的渲染控制,首屏以外体验也有提升。而且开发的时候因为有了 server action 我们也舍弃了笨重的 graphql 直接用 sql 了。
相对的,带来的最大缺点是需要区分服务端和客户端代码以及缓存控制。 |
11
lizy0329 297 天前
关 ssr 什么事情?拿不到时区就渲染个 404 图片,让客户端自己搞
|
12
Charrlles 297 天前 via iPhone
跟客户端有关的信息只能在客户端获取了吧,一味追求纯 ssr 也不太对。像时区这种都还可以存,如果是屏幕宽度之类跟客户端强相关,又不能储存的信息,岂不是懵圈了
|
13
rocmax OP 最后采用的解决方法:
middleware 里判断是否存在 cookie ,不存在的话重定向到/timezone 页面,在页面中有一个 client component ,用 Intl API 获取本地 timezone ,调用 server action 设定 cookie 并重定向回之前的页面。正在尝试做 date-fns 的函数 startOf ,endOf 系列和 format 的自适应,在服务器端根据 cookie 里的时区计算,在客户端使用原函数。 考虑到用户所在时区不会经常变,将其设置了较长的过期时间。以后也可以在页面上搞个按钮来手动改这个 cookie 设定。 代价是首次访问会多跳转一次,之后没有影响。 |
14
rocmax OP 解决方案受下面这篇文章启发,本来也想直接返回 html 内容,但实际用上发现客户端并不会运行其中的 js 函数,而且好像 next12 以后不让直接修改 response body 。于是采用了跳转到空页面的办法。
https://www.jacobparis.com/content/remix-ssr-dates |
16
chenzhe 94 天前
刚从 nextjs13 转到 nextjs14 的时候,脑子里对于哪些部分 server 哪些部分 client 安全是一团乱麻。
写一阵子了稍微好一些了。 |