取势 明道 优术

作者为 扶 凯 发表

在 Mojo 的群中, 大家聊到, 不想新起一个域名, 希望给 Mojo 写的应用挂到一个域名指定的路径下. 来让象 Nginx 和 Apache 之类给前端的请求都调度到后端的 Mojo 的应用. 听讲 Dancer 很容易实现, Mojo 一直没找到方案.所以特地 Google 大神了所有的网站, 找到了解决方案.

默认的 Nginx 放前端 , 比如域名是这样配置的.

    location /mojo {
        #rewrite ^/mojo/?(.*) /$1 break;
        proxy_pass http://127.0.0.1:3000;
    }  


现在的关键是, 需要让所有的请求在 Mojo 的应用中最好都认为是绝对路径, 这个很好实现, 上面我注掉的重写也可以实现.
在这个地方麻烦的是. 如果这个地方有网页的路径输出, 这时输出的绝对路径, 并不会加上 '/mojo' 这样, 在整个 Mojo 应用中输出的路径和地址就都会变得不可用.影响所有的 redirect_to 和 url_for 的输出.

在查询的文章中, 日本一个 Mojo 的玩家也有相同的问题, 并提供了完整的解决方案, 使用 Mojo 的 Hook 功能, 当检查到是使用了 reverse proxy 的时候,给 base path 进行重写. 他的方案如下:

$self->hook('before_dispatch' => sub {
  my $self = shift;
  
  if ( $self->req->headers->header('X-Forwarded-For')) {
    my $prefix = shift @{$self->req->url->path->parts};
    push @{$self->req->url->base->path->parts}, $prefix;
  }
}

当在进入 dispatch 的时候,检查前端是否有 X-Forwarded-For 有就使用了代码, 然后对传送过的路径做为前缀输出. 这时 url_for 和 redirect_to 都正常了.

这二天又认真读了一下文档, 文档 Mojolicious :: Guides :: Cookbook 中也有一个方案, 也很好用.

# Move first part and slash from path to base path in production mode
app->hook(before_dispatch => sub {
  my $c = shift;
  push @{$c->req->url->base->path->trailing_slash(1)},
    shift @{$c->req->url->path->leading_slash(0)};
}) if app->mode eq 'production';

参考文章: reverse proxy use when host name , port number , path correct

来了就留个评论吧! 2个评论



    vvv 2014年06月22日 的 16:12

    求mojo群号。。。