【问题标题】:Strapi custom routes to redirect to public directoryStrapi 自定义路由重定向到公共目录
【发布时间】:2019-08-01 02:05:37
【问题描述】:

我将我的 React 应用程序部署到了strapi 中的/public 目录,一切正常,但是当我刷新页面时,strapi 覆盖了我的react-router routs。

那么...当我使用特定路由时,如何将strapi重定向到打开公共目录?

例如将/posts 重定向到公共目录?

【问题讨论】:

    标签: javascript reactjs redirect react-router strapi


    【解决方案1】:

    Strapi /public 文件夹用于服务器公共资产,而不是托管您的前端应用程序。这样做不是一个好习惯。 在回答你的问题之前,我必须先写下来。

    这是静态文件的服务方式。 https://github.com/strapi/strapi/blob/master/packages/strapi/lib/middlewares/public/index.js 它使用公共中间件。

    因此,您必须按照本文档创建自己的中间件。 https://strapi.io/documentation/3.x.x/advanced/middlewares.html#custom-middlewares

    所以在./middelwares/custom/index.js中添加如下代码:

    const path = require('path');
    
    module.exports = strapi => {
      return {
        initialize: function(cb) {
          strapi.router.route({
            method: 'GET',
            path: '/post',
            handler: [
              async (ctx, next) => {
                ctx.url = path.basename(`${ctx.url}/index.html`);
    
                await next();
              },
              strapi.koaMiddlewares.static(strapi.config.middleware.settings.public.path || strapi.config.paths.static, {
                maxage: strapi.config.middleware.settings.public.maxAge,
                defer: true
              })
            ]
          });
    
          cb();
        }
      };
    };
    

    然后你必须启用你的中间件。 您必须使用以下代码更新 ./config/custom.json 文件:

    {
      "myCustomConfiguration": "This configuration is accessible through strapi.config.myCustomConfiguration",
      "custom": {
        "enabled": true
      }
    }
    

    就是这样!

    【讨论】:

    • 我正在做这样的事情。为此,我遵循此链接。 medium.com/@prakash.gangurde/… 当我将 enable 设置为 true 时,我的管理面板和其他路由会抛出 404。所以你能帮我解决这个问题吗?很抱歉,因为我在听到时添加了 commnet。如果您有我的问题,请告诉我,我可以发布一个新问题。
    • 如果我不知道你的中间件,我真的帮不了你。确保为中间件使用 awaitasync 函数。还要确保你没有设置一个空的身体。
    • 是的,我在应用程序中使用了asyncawait。让我知道您要检查哪个数据/文件。所以我可以和你分享。
    • 你能否在你的路由中添加一个 console.log 并确保你的 ctx.body 不为空。如果您的路线被调用并且您收到404,那是因为正文是空的。
    • 那么,如果/public 不是托管前端应用程序的正确位置,它应该放在哪里?
    【解决方案2】:

    我在构建时构建了我的 Strapi 和 CRA (create-react-app),并说我想将我的 react 应用安装在 /dashboard 路径下。

    文件结构为:

    yourapp/
    └── apps/
        ├── frontend (react app)
        └── backend (strapi)
    
    1. 如果你使用 CRA,在前端的 package.json 添加一个 homepage 属性,这将告诉 Webpack 为你的静态资产添加一个前缀,例如
    // in frontend's package.json
    {
      ...
      "homepage": "/dashboard"
    }
    
    1. 将你构建的 react 应用程序移动到后端项目的子文件夹 /dashboard,通过修改 yarn build 脚​​本,我正在这样做,在复制/粘贴我的代码之前要小心,有一个 rm -rf cmd。
    // package.json in root path
    {
      ...
      "scripts": {
        "build": "yarn build:front && yarn build:back && rm -rf apps/backend/dashboard && mv apps/frontend/build apps/backend/dashboard",
        ...
      }
    }
    
    1. 在 Strapi 中添加一个自定义中间件作为您的“视图路由器”,它将处理对/dashboard/* 的所有请求,以便为apps/backend/dashboard 下的反应应用资产提供服务

    <strapiapp>/middlewares/viewRouter/index.js下创建一个文件

    const path = require("path");
    const koaStatic = require("koa-static");
    const fs = require("fs");
    
    module.exports = strapi => {
      return {
        async initialize() {
          const { maxAge } = strapi.config.middleware.settings.public;
    
          const basename = "/dashboard";
    
          const dashboardDir = path.resolve(strapi.dir, "dashboard");
    
          // Serve dashboard assets.
          strapi.router.get(
            `${basename}/*`,
            async (ctx, next) => {
              ctx.url = ctx.url.replace(/^\/dashboard/, "");
              if (!ctx.url) ctx.url = basename;
              await next();
            },
            koaStatic(dashboardDir, {
              index: "index.html",
              maxage: maxAge,
              defer: false
            })
          );
    
          const validRoutes = [
            "/dashboard",
            "/subpath1",
            "/subpath2"
          ];
    
          // server dashboard assets and all routers
          strapi.router.get(`${basename}*`, ctx => {
            const routePath = ctx.url.split("?")[0];
            let fileName = ctx.url;
            if (validRoutes.includes(routePath)) fileName = "index.html";
    
            ctx.type = "html";
            ctx.body = fs.createReadStream(
              path.join(dashboardDir + `/${fileName}`)
            );
          });
        }
      };
    };
    
    
    1. 启用<strapiapp>/config/custom.json中的自定义中间件
    {
      "myCustomConfiguration": "This configuration is accessible through strapi.config.myCustomConfiguration",
      "viewRouter": { // use the middleware name
        "enabled": true
      }
    }
    

    并访问http://localhost:1337/dashboard,您将看到反应页面。

    【讨论】:

    • 烦人你必须在这里手动添加有效路线。我只希望它允许任何路线,但保持 /admin 运行strapi admin
    • @xaunlopez 为什么你不能写一个中间件来接受任何路由?
    • @chishaku 我试过了,但是在为前端资产选择除“/admin”之外的任何路由时遇到了麻烦。我找不到 router.get 字符串 arg 的可接受排除模式。也许你能弄清楚?但最后我意识到它可能应该是单独的并使用 nginx 反向代理。
    猜你喜欢
    • 1970-01-01
    • 2021-04-05
    • 2018-11-30
    • 2016-07-03
    • 1970-01-01
    • 2017-03-18
    • 1970-01-01
    • 2021-12-18
    • 2017-09-12
    相关资源
    最近更新 更多