评论

收藏

[JavaScript] #yyds干货盘点# Next.js通配符子域

开发技术 开发技术 发布于:2021-12-13 17:12 | 阅读数:517 | 评论:0

Next.js通配符子域
快速总结 ↬ 使用通配符子域的主机使你的用户能够在你的域名(<em>.example.com)的任何子域上访问你的网站,正如你所想象的,我们可以利用这一点来创造独特的用户体验,我们将在本文中通过Next.js镜头来探索。
一个 "通配符"?这到底是什么?好问题,这些类型的域名源于通配符DNS记录,看起来像这样。
*.example.         3600   TXT   "Wild! You have found a wildcard."
当使用时,这个DNS记录将导致任何与通配符匹配的子域持有一个文本值。“Wild! You have found a wildcard.”
例如,如果在域名smashingmagazine.com上设置了这个,apples.example.smashingmagazine.com和oranges.example.smashingmagazine.com都将返回上述文本值。同样的原则也可以应用于CNAME和A记录。

通配符的广泛使用案例
通配符可以用来做很多事情。现在,让我们关注一下它们在Next.js中的应用。
1.提供托管服务
通配符域名最常见的用途是为托管服务的用户提供他们自己的空间,并有一个独特的子域。例如,如果我正在为餐馆建立一个平台,用域名menus.abc来托管数字订购平台,我将能够为Dom's Pizzeria提供domspizzeria.menus.abc,为Magical Prata提供域名magicalprata.menus.abc。这样做的好处是,它给了这些机构各自一个封闭的空间,他们可以定制和建立。这个空间可以作为它自己的网站--不受任何约束。
2.托管内容和个人公文包
通配符也可以用作作品集的内容托管空间,给这些作品集带来一种个性化的感觉,一个例子是Medium如何为作者提供子域名。
3.更多创造性的使用案例
你无法定义这些用例,但这些风格的领域有很多创造性的用例。例如,在本文后面,我们将开发一个网页玩具,将网页翻转过来,使其对澳大利亚人来说可读。

使用Next.js的通配符的注意事项
遗憾的是,使用通配符并不完美,有几个缺点。

  • 不再有静态站点生成(和ISR)
    不幸的是,没有任何特殊的系统可以为不同的通配符子域提供定制的静态生成的页面,比如你可以用动态路由(你有[slug].js文件)。
  • 发展方面的困难
    在本地开发时,模拟通配符域名可能是件麻烦事,我们将在本文的后面部分触及这个问题,但这是需要牢记的事情。
  • 有限的部署平台
    Vercel支持通配符域名,然而,其他面向Jamstack的平台并不都支持通配符域名。例如,Netlify将该功能限制在专业计划的特定用户群中。

用通配符构建
说了这么多,让我们来看看用这些域名进行建设。我们将重点讨论你可以获得通配符的三个地方。
1.Server Side In getServerSideProps,
2.Client Side With useEffect,
3.Server Side On API Routes and Edge Functions。
在getServerSideProps中的服务器端
这是最常见的需要提取通配符的情况,你可以在需要为不同通配符渲染完全不同内容的页面上使用。如上所述,这不能通过静态网站生成来完成,所以我们必须在服务器端渲染的页面上完成。
getServerSideProps被传递给一个上下文对象,在这个对象中你可以使用context.req访问HTTP请求对象。在这个请求对象中,你可以在headers.host处访问主机名,它将返回一个字符串,如example.yourdomain.com。我们可以把这个字符串分割成一个数组,跨越每个周期,然后访问所述数组中的第一个项目。在代码中,这看起来像这样:
async function getServerSideProps(context) {
  let wildcard = context.req.headers.host.split(".")[0];
  wildcard =
  wildcard != "yourdomain"
    ? process.env.NODE_ENV != "development"
    ? wildcard
    : process.env.TEST_WILDCARD
    : "home";
  return { props: { wildcard } };
}
正如你在这段代码中看到的,我们对通配符做了一个额外的设置处理,如果它是基本域,我们将通配符设置为home(如果接受用户输入,这是你需要处理的情况),如果我们在localhost上测试,我们可以测试出其他通配符。在我们的默认导出函数中,渲染我们的页面,我们可以使用一个开关语句来处理通配符。
default function App(props) {
  switch(props.wildcard) {
  case "home":
    return &lt;div&gt;Welcome to the home page!&lt;/div&gt;;
    break;
  default:
    return &lt;div&gt;The wild card is: {props.wildcard}.&lt;/div&gt;;
  }
}
使用'useEffect'的客户端
如果你只想在不同的通配符上对每个页面进行小的修改,你可以通过在客户端使用useEffect钩子来避免使用服务器端的渲染。这种方法将相当类似于我们在getServerSideProps中的做法,只是我们将依赖window.location.hostname。使用window意味着最初的服务器渲染将无法访问这些信息,所以我们必须将其包裹在一个在客户端运行的useEffect钩子中。下面是这段代码的模样。
// useEffect and useState must be imported from 'react'
const [wildcard, setWildcard] = useState("")
  useEffect(() =&gt; {
  setWildcard(window.location.hostname.split(".")[0])
  }, [])
然而,这种方法远非完美,因为在页面的第一次渲染和通配符可用之间有一个延迟。因此,如果你在通配符的基础上做大幅度的改变,那么这些改变对你的用户来说会很刺耳。这也可能会伤害到你的网络生命力上的累积布局转变措施。考虑到这一点,我强烈建议你将这种方法的使用限制在最初加载时不被浏览者看到的调整上。一个例子是技术文档页面上的品牌页脚。当然,这仍然是很容易知道的。
服务器端的api路由和边缘功能
API路由是另一个你可能想要访问通配符的地方。幸运的是,我们在上面关于 "getServerSideProps "一节中讨论的请求对象,在使用Next.js的Node.js API路由时也是可用的。我们可以像这样访问它。
default (req, res) =&gt; {
  let wildcard = req.headers.host.split(".")[0];
  wildcard =
  wildcard != "yourdomain"
    ? process.env.NODE_ENV != "development"
    ? wildcard
    : process.env.TEST_WILDCARD
    : "home";
  res.json({ wildcard: wildcard })
}
在这之后,我们可以采取某些行动,例如根据通配符从你的数据库中获取不同的数据,并从API中返回这些数据。
这种逻辑也可以应用于Next.js的新边缘函数/中间件。这使你能够在一个以上的路由中使用通配符,而无需重复代码,并加快处理速度,因为代码执行发生在边缘。虽然该功能仍处于测试阶段,但它肯定是值得关注的。
// _middleware.js
export function middleware(req) {
  let wildcard = req.headers.get("host").split(".")[0];
  console.log(wildcard);
  wildcard =
  wildcard != "yourdomain"
    ? process.env.NODE_ENV != "development"
    ? wildcard
    : process.env.TEST_WILDCARD
    : "home";
  console.log(process.env.TEST_WILDCARD);
  return new Response(JSON.stringify({ wildcard: wildcard }), {
  status: 200,
  headers: { "Content-Type": "application/json" },
  });
}
The
关注下面的标签,发现更多相似文章