首页 文章

快递,如何通过长 URL 路径反应路由器?

提问于
浏览
3

有太多第三方的东西正在发生,我甚至不知道如何准确地说出这个问题,但让我试着解释一下我想做什么:

我的 webapp 是一个 react/redux/react-router/redux-router/webpack webapp,我使用快速服务器来解决直接从客户端到另一个域上的服务器的 CORS 问题。

Express 在端口 3000 上运行,webpack dev 服务器在端口 8080 上运行

这是我的快速设置(据我所知,它太复杂了,但是在做 webdev 时有很多库需要学习,有时你只需要工作而不是花 3 天时间调查每个 lib):

app.use(express.static(path.join(__dirname, '/dist/')));

  var proxyRules = new HttpProxyRules({
      rules: {
        '.*/broker': 'https://SomeDomain.com/broker/', 
        '.*/api': 'https://api.AnotherDomain.com/'
      }
    });

  var bundle = require('./bundle.js');
  bundle();

  var proxy = httpProxy.createProxyServer();

  proxy.on('error', function(e) {

  });

  // Any requests to localhost:3000/dist is proxied
  // to webpack-dev-server
  app.get('/bundle.js', function (req, res) {
    proxy.web(req, res, {
        target: 'http://localhost:8080/dist',
        changeOrigin:true
    });
  });

  app.all('/dist/*', function (req, res) {
    proxy.web(req, res, {
        target: 'http://localhost:8080',
        changeOrigin:true
    });
  });

  app.get('/img/:name', function(request, response){
    const name = request.params.name
    response.sendFile(path.join(__dirname, '/../dist/img/' + name));
  });

  app.get('/css/fonts/:name', function(request, response){
    const name = request.params.name
    response.sendFile(path.join(__dirname, '/../dist/css/fonts/' + name));
  });

  app.get('/css/:name', function(request, response){
    const name = request.params.name
    response.sendFile(path.join(__dirname, '/../dist/css/' + name));
  });

  app.all('*', function(req, res) {
     var target = proxyRules.match(req);
    if (target) {
       return proxy.web(req, res, {
         target: target
      });
    } else {
      res.sendFile(path.join(__dirname, '/../dist/index.html'));
    }
 })

简而言之:webpack 编译到dist文件夹。我将我的静态资产(图像等)复制到dist/imgdist/css等。

现在我在上面的配置中设置了一堆规则:

  • 当它寻找静态资产时,它返回那些(img,css,font)

  • 如果 url 与代理中的规则匹配,则代理 url 以执行没有 CORS 问题的 server-server 请求

  • 如果要求 webpack 生成的bundle.js文件,则返回该文件

  • 所有localhost:3000/dist调用都重新映射到运行 webpack dev 服务器的端口 8080

  • 所有剩余的东西(*)返回 index.html

现在的问题是确保反应路由正常工作(它们使用 url 中的相对路径)。

在当前配置中,如果我打开诸如http://localhost:3000/dashboardhttp://localhost:3000/location之类的 URL,它可以很好地工作,但是如果我尝试了http://localhost:3000/dashboard/profile/user5样式的 url,它似乎会回退到想要返回的*规则index.html

如何解决这个问题,以便将完整路径传递给 client-side 路由器?

这是 client-side 配置

export const routes = (
  <Route component={Application} name="application">
    <Route component={Home} path="/"/>
    <Route component={Login} path="/login"/>
    <Route component={requireAuthentication(Dashboard)} path="/dashboard"/>
    <Route component={requireAuthentication(Locations)} path="/locations"/>
    <Route component={requireAuthentication(EditLocationTemplate)} path="/locations/template/location"/>
    <Route component={NotFound} path="*" />
  </Route>
);

如果您对 Express 的常规设置有任何意见,我很满意。还在学习如何使用这一切,所以我确信这远非最佳配置。

谢谢!

1 回答

  • 1

    快速路线将按照您创建它们的顺序匹配,最终回落到您上次的“全部捕获”路线(app.all('*'))。

    因为你没有为/dashboard/profile/user5之类的路线写过任何匹配,所以它基本上就像你所要求的那样,并且默认为 catch-all 路线。

    如果您想轻松处理这些问题,可以创建一个包含子级的顶级路由列表,并相应地匹配这些路由:

    var routesWithChildren = [
          '/dashboard',
          '/locations'
        ];
    
        routesWithChildren.forEach(function (rootPath) {
            app.get(rootPath + '/*', function (req, res) {
              // Send or render whatever is appropriate here
              // You can use req.path to get the path that was requested
              // Eg: /dashboard/profile/user5
            });
        });
    

相关问题