- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
目标
我希望对特定 URL ( /dashboard
) 下的内容使用仅限客户端的路由。其中一些内容将来自 Contentful 并使用页面模板。这条路线的一个例子是 {MYDOMAIN}/dashboard/{SLUG_FROM_CONTENTFUL}
.这样做的目的是确保我在代理机构工作过的项目无法被抓取/访问,并且只有在登录后才对“雇主”可见。
我试过的
我的页面是通过 gatsby-node.js
生成的.添加身份验证/仅客户端路由的方式取自 this example .据我所知,现在它的基础已经设置好并且工作正常。但是私有(private)路由似乎只在以下情况下有效:
如果我登录并导航到 /dashboard
Profile.js
/dashboard
Login.js
/dashboard/url-from-contentful
时,问题就出现了并且我没有登录。我得到了页面而不是被发送到
/dashboard/login
.
exports.createPages = async ({graphql, actions}) => {
const { createPage } = actions;
const { data } = await graphql(`
query {
agency: allContentfulAgency {
edges {
node {
slug
}
}
}
}
`);
data.agency.edges.forEach(({ node }) => {
createPage({
path: `dashboard/${node.slug}`,
component: path.resolve("src/templates/agency-template.js"),
context: {
slug: node.slug,
},
});
});
}
exports.onCreatePage = async ({ page, actions }) => {
const { createPage } = actions;
if(page.path.match(/^\/dashboard/)) {
page.matchPath = "/dashboard/*";
createPage(page);
}
};
我的
auth.js
已设置(用户名和密码是基本的,因为我仍然只在本地开发):
export const isBrowser = () => typeof window !== "undefined";
export const getUser = () =>
isBrowser() && window.localStorage.getItem("gatsbyUser")
? JSON.parse(window.localStorage.getItem("gatsbyUser"))
: {};
const setUser = (user) =>
window.localStorage.setItem("gatsbyUser", JSON.stringify(user));
export const handleLogin = ({ username, password }) => {
if (username === `john` && password === `pass`) {
return setUser({
username: `john`,
name: `Johnny`,
email: `johnny@example.org`,
});
}
return false;
};
export const isLoggedIn = () => {
const user = getUser();
return !!user.username;
};
export const logout = (callback) => {
setUser({});
call
};
PrivateRoute.js
设置如下:
import React from "react";
import { navigate } from "gatsby";
import { isLoggedIn } from "../services/auth";
const PrivateRoute = ({ component: Component, location, ...rest }) => {
if (!isLoggedIn() && location.pathname !== `/dashboard/login`) {
navigate("/dashboard/login");
return null;
}
return <Component {...rest} />;
};
export default PrivateRoute;
dashboard.js
有以下内容。行
<PrivateRoute path="/dashboard/url-from-contentful" component={Agency} />
,我在这里尝试了几件事 - 静态输入路线并使用
exact
prop,使用路由参数,如
/:id
,
/:path
,
/:slug
:
import React from "react";
import { Router } from "@reach/router";
import Layout from "../components/Layout";
import Profile from "../components/Profile";
import Login from "../components/Login";
import PrivateRoute from "../components/PrivateRoute";
import Agency from "../templates/agency-template";
const App = () => (
<Layout>
<Router>
<PrivateRoute path="/dashboard/url-from-contentful" component={Agency} />
<PrivateRoute path="/dashboard/profile" component={Profile} />
<PrivateRoute path="/dashboard" />
<Login path="/dashboard/login" />
</Router>
</Layout>
);
export default App;
最后
agency-template.js
import React from "react";
import { graphql, Link } from "gatsby";
import styled from "styled-components";
import SEO from "../components/SEO";
import Layout from "../components/Layout";
import Gallery from "../components/Gallery";
import GeneralContent from "../components/GeneralContent/GeneralContent";
const agencyTemplate = ({ data }) => {
const {
name,
excerpt,
richDescription,
richDescription: { raw },
images,
technology,
website,
} = data.agency;
const [mainImage, ...projectImages] = images;
return (
<>
<SEO title={name} description={excerpt} />
<Layout>
<div className="container__body">
<GeneralContent title={name} />
<Gallery mainImage={mainImage} />
<GeneralContent title="Project Details" content={richDescription} />
<div className="standard__images">
<Gallery projectImages={projectImages} />
</div>
<ViewWebsite>
<Link className="btn" to={website}>
View the website
</Link>
</ViewWebsite>
</div>
</Layout>
</>
);
};
export const query = graphql`
query ($slug: String!) {
agency: contentfulAgency(slug: { eq: $slug }) {
name
excerpt
technology
website
images {
description
gatsbyImageData(
layout: FULL_WIDTH
placeholder: TRACED_SVG
formats: [AUTO, WEBP]
quality: 90
)
}
richDescription {
raw
}
}
}
`;
export default agencyTemplate;
我认为 Gatsby 可以从 CMS 中选通内容,但考虑到它是 SSG,我可能错了。我可能误解了仅限客户端的基本原理。 React 中的概念和使用 Gatsby 对我来说仍然很新,所以任何帮助或指导实现目标将不胜感激。
useContext
或 redux 帮助我了解我哪里出错了。
gatsby-node.s
),而是通过处理路由和 GraphQL 以“React 方式”(我知道 Gatsby 是用 React 构建的)来完成它变得更加清晰。除了身份验证之外,我最终所做的只是创建一个新的
<Agency />
组件并将来自 GraphQL 的数据输入其中并使用我的
map()
更新路径.
return (
<>
<Router>
<DashboardArea path="/dashboard/" user={user} />
{agencyData.map(({ node }, index) =>
node.slug ? (
<Agency key={index} data={node} path={`/dashboard/${node.slug}`} />
) : null
)}
</Router>
</>
);
最佳答案
我假设在您的 PrivateRoute 组件中,您错误地使用了 isLoggedIn 检查。从 auth.js 导入和使用 isLoggedIn 只会在最初运行,不会充当监听器。您可以做的是将 isLoggedin 的值存储在全局状态变量中,例如(useContext 或 redux),并制作一个自定义 Hook 来检查登录状态。其次避免直接访问localStorage,而是使用全局状态管理(useContext,redux)或本地状态管理(useState,this.state)。
注意:当您通过直接在浏览器中粘贴 url 来访问路由时,它总是会刷新页面并且您存储的所有状态都会重新初始化。这可能是您遇到此问题的原因。浏览器不知道您之前已登录,因此它始终会在您的应用程序安装后进行验证。您可以做的是,您可以将 isLoggedIn 状态存储在浏览器的本地存储中。我个人喜欢为此使用 redux-persist。
export const useGetUser = () => { //add use infront to make a custom hook
return useSelector(state => state.gatsByUser) // access user info from redux store
};
export const handleLogin = ({ username, password }) => {
//suggestion: don't validate password on client side or simply don't use password,
//instead use tokens for validation on client side
if (username === `john` && password === `pass`) {
dispatch(setUserInfo({
username: `john`,
name: `Johnny`,
email: `johnny@example.org`,
isLoggedIn: true,
}));
return true;
}
return false;
};
// adding 'use' infront to make it a custom hook
export const useIsLoggedIn = () => {
//this will act as a listner when ever the state changes
return useSelector(state => state.gatsByUser?.isLoggedIn ?? false);
};
export const logout = (callback) => {
const dispatch = useDispatch(); // redux
dispatch(clearUserInfo());
};
现在在私有(private)路线做
import React from "react";
import { navigate } from "gatsby";
import { useIsLoggedIn } from "../services/auth";
const PrivateRoute = ({ component: Component, location, ...rest }) => {
const isLoggedIn = useIsLoggedIn();
if (!isLoggedIn) {
return navigate("/dashboard/login");
}
return <Component {...rest} />;
};
export default PrivateRoute;
关于javascript - 将仅客户端路由与来自 Contentful 的页面模板一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68831676/
什么是 SASS 方法要求干燥这样的东西: .content p, .content ul, .content li, .content a 最佳答案 这 4 个元素都有共同的样式吗? .conten
我正在评估 Contentful.com 作为 Angular SPA 的内容引擎。 我面临的问题是按内容类型检索条目(例如,获取“博客”类型的所有条目)。如 documentation exampl
在我编辑的主 wiki 上有一个名为 Item: 的自定义命名空间,提示是该命名空间内的每个页面都显示为 Item:This_item - - Item:That_item -- Item:Foo_i
我正在尝试编写一个Python脚本,可以将图片和pdf上传到WordPress。我希望图像上传到文件夹‘/wp-Content/Uploads/’,将pdf文件上传到文件夹‘/wp-Content/U
是否可以监控进行了多少次 Contentful API 调用,并理想地在即将超过配额时收到通知? 谢谢 最佳答案 当然,您可以在右侧用户配置文件的下拉菜单 > Organizations and Bi
我在尝试在 IE8 中下载带有分号的文件名时遇到问题。 Response.AddHeader("Content-Disposition", "attachment; filename=\"" + at
我在 Contentful Delivery API 中运行查询以返回基于它的 slug 的特定页面项目。这个查询还设置了语言环境,以便它只返回我需要呈现的语言的数据。 但是,我还需要设置页面的 hr
我有兴趣使用 Gatsby建一个Netlify使用来自 Contentful 的内容的静态网站 Netlify 有这个不错的 Gatsby 入门指南: https://www.netlify.com/
目标是提交一个 git 分支。分支的“git status”的输出是: On branch zeromq_new Your branch is up to date with 'origin/zero
我目前正在学习在 ASP.NET 3.5 和 C# 中使用 MasterPages 和 ContentPlaceHolders - 现在,我正在拼命尝试通过我的编程代码编辑 asp:Content-C
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我使用 bootstrap 3 作为我的网格框架和 CSS 来创建一个具有一个倾斜/倾斜边缘的半透明区域,但由于分层不透明度,我的元素遇到了问题。 期望是中心是倾斜的,但右侧仍然是正方形。 有没有更好
IllegalArgumentException: 未知 URL 内容:// ^ 对上述内容做了噩梦。我检查了我的变量和路径,但看不出问题是什么?非常感谢任何指点! 这是我的痕迹。 java.lan
我有两个元素:一个是 元素,另一个是 元素。 populated-drop-down extends drop-down ,但是,正如您可能已经猜到的那样,它会尝试使用一些选项预先填充它。假设我可以简
我想我也有同样的问题。 Using multiple yields to insert content 我尝试了这个解决方案。我试过 在我的 application.html.erb 中有 conte
此链接 ( https://css-tricks.com/snippets/css/a-guide-to-flexbox/ ) 表示 justify-content 和 align-content 的
我现在正在探索绑定(bind),并且有一个 NSPopUpButton - 它为我提供了一些值选择下的绑定(bind)选项 - Content , Content Objects , Content
正在尝试在内容页面中加载内容 View 。当我运行代码时,它不会出现在我的内容 View 中。我正在从我的内容页面分配两个可绑定(bind)参数。 内容页面: 内容 View :
我想从我的 :before 标签中获取 content。我知道有些人会说它不是真正的(伪)元素,但在 JS 中有一种方法,但有人可以帮助我在 JQ 中做到这一点,因为我有多个标签并且我想用 $.eac
我创建了一个.sh脚本,并将结果记录在一个文件中,执行后我会尝试将文件内容作为mail正文发送。 这是我运行的命令: sh update.sh >> update.$(date +"%Y-%m-%d:
我是一名优秀的程序员,十分优秀!