这篇文章上次修改于 5 个月前,可能其部分内容已经发生变化,如有疑问可询问作者。
背景
现在很多网站都使用了前后端的分离的架构,前后端可以不在一台服务器上,前端为了保证 SEO,必须使用预渲染,SSG 或 SSR 技术。而我的站点则使用了 NextJS 的 SSR 技术。在渲染端预渲染页面时首先会调用 Axios 实例去请求接口。但是有一个问题。在渲染端请求的头部永远是渲染端本身的 User-Agent 和 IP,并不能获取到用户本身的元数据。显然这并不是我们先要期望得到的结果。当然这个情况只发生在首次访问。
为了解决这种问题,必须想办法把原本的请求头部或者其他元数据转发到此次请求上。有点类似反向代理,但是又有点不同。好在 NextJS 为我们提供了这一接口。
踩坑之路
带着这个想法,我踩了很多坑。
首先我查到 NextJS 可以在 Custom App 上定义
getInitialProps
(和 NextPage 一致)。但是它接受一个参数,类型为 AppContext
位于 next/app
包中。getInitialProps
必须返回一个对象,但是因为他是 Root Component。必须接受所有 Children props,然后返回。好在 NextJS 为我们提供了一个方法,我们只需要如下操作就能完成建基。之后我们需要进行扩展。
首先我们要知道
props
上有一个 ctx
的对象,ctx
中有一个 req
对象,类型为 IncomingMessage
。这个 req
对象就是用户的请求,我们只需要把这个 req
中的某些元数据附加到之后请求的 axios
实例上即可。当然只需要判断是不是在预渲染的时候就行了,因为如果不在渲染端就不需要做转发。我们可以使用
typeof window === 'undefined'
来判断是否在渲染端。之后就是怎么获取到用户的真实 IP 了,如果使用了 Nginx 或者其他服务器软件进行反代,一般会把真实 IP 附加到 Headers 上。
之后就是怎么附加到 Axios 上。这里有一个坑,不要直接附加到 Axios.default.headers 上,因为这样看似可以(的确只在 dev 环境可以),但是 production 立马暴毙,血的教训
我们可以附加到 Axios 实例上。直接在
service.default.headers.common
上对键进行赋值即可。而获取 UA 就简单了,直接
request.headers['user-agent']
就能拿到。以上就是完整的代码了。
文章标题:
文章作者:
文章链接: [复制]
最后修改时间:
商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,未经站长允许不得对文章文字内容进行修改演绎。
本文采用创作共用保留署名-非商业-禁止演绎4.0国际许可证
亲亲留个评论再走呗
正在加载评论区...