Nginx重写规则用下划线replace查询string问号

为了将整个网站镜像为静态HTML,

我想将urlhttp://example.com/script.php?t=12转换为http://example.com/script.php_t=12

注意? 在URL正在被转换为_

这将允许nginx或apache从磁盘提供这些文件作为我们获得的原始HTML,并从wget保存 – 每个URL的一个文件 – 而不是一个PHP文件。

是否有可能通过Nginx的URL重写?

我得到这个工作使用try_files:

 location / { try_files "${uri}_${args}" 404.html; } 

这将尝试在磁盘上find一个以“_”而不是“?”提供的模式命名的文件。

进一步的configuration取决于你如何保存静态文件,如图像或样式表。 您可以添加一个回退尝试读取它们,而不需要查询stringforms的磁盘,如下所示:

 location / { try_files "${uri}_${args}" $uri 404.html; } 

沿线的东西:

 location ~ \.php$ { # only rewrite URL's with args if ($args != '') { rewrite .* "${uri}_${args}?" last; } } 

我不认为你可以用香草nginx做到这一点,但如果你愿意安装nginx的Lua模块( http://wiki.nginx.org/HttpLuaModule ),你可以做到这一点。

 server { server_name so.dev; listen 80; location / { root /tmp; rewrite_by_lua ' local uri = ngx.var.uri local params = ngx.req.get_uri_args(0) for key, value in pairs(params) do uri = string.format("%s_%s=%s", uri, key, value) end ngx.req.set_uri(uri) ngx.req.set_uri_args({}) '; } } 

在当地testing它,似乎做你正在寻找。 如果你想保持由&符号隔开的其他参数,将rewrite_by_lua块更改为

 local uri = ngx.var.uri local param_string = "" local params = ngx.req.get_uri_args(0) local separator = "" for key, value in pairs(params) do param_string = param_string .. separator .. key .. "=" .. value separator = "&" end ngx.req.set_uri(uri .. "_" .. param_string) ngx.req.set_uri_args({}) 

这适用于nginx / 1.6.2。

 rewrite ^/.*\.php$ "${uri}_${args}"; 

但个人来说, 如果有的话,我会使用try_files解决schemetry_files退原始URI。

 try_files $uri "${uri}_${args}"; 

例如,如果你在磁盘上有script.php ,它会首先尝试,然后,如果没有,它会去script.php_t=12try_files需要一个最新版本的nginx。

如果这还不够,你可以这样做:

 return 301 "${uri}_${args}"; 

维基说

如果你指定一个? 在重写结束后,Nginx将放弃原始$ args(参数)。

那么rewrite ^ ${uri}_$args? last; rewrite ^ ${uri}_$args? last; 应该工作。

上面提出的答案应该可以工作。 但是,您会看到您的url变得非常敏感。 因为nginx试图检查服务器上是否存在文件名,所以任何额外的参数都会抛出。

 http://example.com/script.php?t=12 // works http://example.com/script.php?t=12&_utm=twitter // not work 

我的build议是保持原样的URL和路由到正确的文件与PHP。 您可以访问t参数。