当在“生产”中直接在浏览器中访问URL时,只有GatsbyJs客户端的路径会转到404页

时间:2018-08-28 06:03:07

标签: gatsby

我已经创建了一个盖茨比应用程序,并将gatsby-node.js配置为仅创建客户端的路径,这些路径在开发中都可以正常工作,而直接访问路径的url却不在生产环境中。

示例:

if(page.path.match(/^\/sample/)){
     page.matchPath = "/sample/:value1/:value2/:value3";
     createPage(page)
  }

我正在使用heroku来部署应用程序

9 个答案:

答案 0 :(得分:7)

原因

尽管客户端路由器知道此路径,但没有相应的HTML文件。当浏览器查看该站点时,它首先加载由gatsby生成的404.html文件,其中包括客户端路由器。路由器完成初始化后,将读取路径并加载正确的页面。意味着您最终到达了正确的位置,但是到达错误页面的时间只有半秒钟。

如何修复

一般的解决方案是告诉服务器将/sample/路径重定向到您的/sample/index.html文件。进行此操作的方式取决于您的主机,但是我将为各种主机提供该技术的名称,以防您需要查找它。通常称为URL重写,每个主要的托管平台都应支持它。

Heroku

gatsby deploy documentation的Heroku部分建议使用heroku-buildpack-static模块,该模块内置了对“自定义路线”的支持,它将使用以下语法为您的情况解决此问题:

{
  "routes": {
    "/sample/**": "sample/index.html",
  }
}

答案 1 :(得分:3)

这解决了我的问题

pages/404.jsx

import React, { useEffect, useState } from 'react';

export default ()=>{
  const [isMount, setMount] = useState(false);
  
  useEffect(() => {
        setMount(true);
  },[])

  if(!isMount) {
     return(
        <div>loading</div>
     )
  }

  return (
     <div>Page Not Found</div>
  )


}

在响应为 404 之前,这不会在客户端呈现上显示 404 错误。

答案 2 :(得分:1)

对于使用S3(gatsby-plugin-s3)和CloudFront的任何人,我已通过在gatsby-plugin-s3配置中添加generateMatchPathRewrites: false并为原始请求创建Lambd @ Edge函数来解决302/404问题使用以下代码:

exports.handler = async (event) => {
  const request = event.Records[0].cf.request;
  if (/^\/app\//i.test(request.uri)) {
      request.uri = '/app/index.html';
  }
  return request;
};

尽管302/404消失了,但是在进行强制刷新时仍然遇到问题。例如,当我在/ app / page2并单击刷新时,/ app中的默认组件将加载,然后半秒后,/ app / page2中的组件将显示,但方式很奇怪。 / app的某些CSS类混在/ app / page2中。如果有人对此有任何想法,请告诉我。

答案 3 :(得分:0)

我在公用文件夹中查找了我创建的客户路由的索引文件

对于netlify,我在根目录的netlify.toml文件中添加了以下内容。


[[redirects]]
  from = "/user/dashboard/"
  to = "/user/index.html"
  status = 200

答案 4 :(得分:0)

对于Firebase托管,我在firebase.json中添加了以下内容:

"rewrites": [
  {
      "source": "**",
      "destination": "/loading/index.html"
  }

]

然后我在loading.js下创建了一个新的/page文件。使用此配置,Firebase首先使用loading.html进行响应,然后Gatsby处理客户端路由。

答案 5 :(得分:0)

heroku 解决方案对我不起作用,但我不知道确切原因。我的前端正在从 express.js 后端获取数据。我通过在我的 server.js 中添加以下几行来重定向我的客户只路由来解决我的问题。

app.get('/user/**', (req, res) => {
  res.sendFile(path.join(`${__dirname}/public/user/index.html`));
});

答案 6 :(得分:0)

维塞尔

对于希望在 Vercel 平台上解决此问题的任何人,答案是重写:https://vercel.com/docs/configuration#project/rewrites

如果您有一个只有客户端路径的 gatsby 应用程序,例如 https://www.gatsbyjs.com/plugins/gatsby-plugin-create-client-paths/,您很可能会在部署时遇到这个问题。

示例:您的应用程序的路径类似于 mything.com/app/user-profile

在这种情况下,app/* 是客户端专用的路由,不会在服务器上生成,因此当您重新加载此路由或登陆该路由时,您可能会收到 404 的闪现例如,直接来自外部链接。

要解决,请在 Vercel 中的 /app/* 服务器端路由上添加重写以指向 /app,假设您的路由受到控制通过 Reach 路由器或您的 pages/app.js 文件中的类似文件。

要在 Vercel 上进行设置,请在 gatsby/react 项目的根目录中创建 vercel.json 并添加以下配置:

{
  "rewrites": [{ "source": "/app/:match*", "destination": "/app" }]
}

此问题通常仅在部署到生产/暂存时才会出现。它不会在开发中发生(无论如何通过 gatsby develop)。

答案 7 :(得分:0)

对于本地开发,您必须使用神奇的 [...].js 文件名。

您可以在此处查看演示存储库:https://github.com/gatsbyjs/gatsby/tree/master/examples/client-only-paths/src/pages

答案 8 :(得分:0)

NGINX

如果您的环境包含 Nginx,您应该在您的虚拟主机配置中添加如下内容:

rewrite ^/products/([0-9]*)$ /products/[id]/index.html;

rewrite ^/users/confirm/(.*)$ /users/confirm/[code]/index.html;

只需转到您的生产根目录并为您的案例查找 index.html 文件的正确路径。

通常您的虚拟主机配置位于:/etc/nginx/sites-enabled/mysite.com.conf