我试着按照文档中的示例,如何设置baseQuery
发送头,在我的例子中是用于身份验证
const baseQuery = fetchBaseQuery({
baseUrl: '/',
prepareHeaders: (headers, { getState }) => {
const token = (getState() as RootState).auth.token
// If we have a token set in state, let's assume that we should be passing it.
if (token) {
headers.set('authorization', `Bearer ${token}`)
}
return headers
},
})
这是我如何设置我的getServerSideProps
export const getServerSideProps = wrapper.getServerSideProps(
store =>
async ({ locale, params }) => {
const slug = params?.slug;
if (typeof serviceProviderSlug === "string") {
store.dispatch(getOrders.initiate());
}
await Promise.all(getOrderRPOs());
return {
props: {
...(locale &&
(await serverSideTranslations(locale, ["common", "orders"]))),
},
};
}
);
我使用redux-persist
将令牌存储在本地存储中。当页面在初始页面上刷新时,存储不能读取令牌,并且它将发送网络请求,并且发送的请求将在客户端呈现中。
我做错了什么?以及如何为服务器端渲染设置正确的基本查询?
2条答案
按热度按时间cld4siwp1#
我想我已经在Github上回答了这个问题,但既然你先问这里,我也会在这里回答:
好吧,Redux存储在服务器上总是空的-- SSR总是为每个请求使用一个“新的”Redux存储,因为从技术上讲,客户端无法将完整的存储内容传递回服务器。
您可以在每次请求时将数据从服务器存储移动到客户机存储(使用redux-next-wrapper提供的水合选项),但不能反过来。
如果你想在客户端和服务器之间共享令牌之类的东西,你必须把它放到一个cookie中,然后在
prepareHeaders
中访问这个cookie,而不是放到你的Redux存储中。zzwlnbp82#
为了解决您的问题,您需要了解为什么我们使用next.js我花了一段时间才理解,但答案是您不应该或不需要在SSR或SSG中传递auth Token。
你可能不知道这一点,但是当你在正常的react中使用useEffect()获取数据时,它首先呈现一个空div(或加载页面),然后在获取数据后,它呈现带有数据的页面,所以当SEO Bot抓取该页面时,它索引空页面,而不是带有数据的页面!.
为了解决这个问题,我们使用next.js SSR或SSG,它在构建或运行时预渲染数据,这使得我们的页面具有获取的数据可以被SEO机器人抓取。
SEO机器人可以永远不会绕过身份验证,所以如果你是SSR或SSG来获取需要auth令牌的数据,那么SEO将永远无法抓取它。因此,将事情复杂化并使用SSR或SSG来获取私有数据是绝对无用的。因此,只需绕过HYDRATION错误并使用Axios或SWR