重写nginx规则(Opencart)

Opencart有这个URL结构:

http://example.com/index.php?route=common/home http://example.com/index.php?route=account/register http://example.com/index.php?route=checkout/cart http://example.com/index.php?route=checkout/checkout 

…我想从index.php?route=直到第一个/ ,正则expression式是index.php\?route\=[^\/]*\/ ,所以所需的url将是,例如, http://example.com/checkout

我试过了:

 location @opencart { rewrite index.php\?route\=[^\/]*\/ / last; rewrite ^/(.+)$ /index.php?_route_=$1 last; } 

也试过:

 location / { if ($query_string ~ "^route=common/home$"){ rewrite ^/index\.php$ http://www.example.com? redirect; } } 

…但目前为止还没有运气,我仍然可以在URL中看到route=common/home

这是我目前的Nginxconfiguration:

 location / { try_files $uri @opencart; } location @opencart { rewrite ^/(.+)$ /index.php?_route_=$1 last; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.0-fpm.sock; } location ~* \.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|\.php_ { deny all; } location ~ /\.ht { deny all; } location /image/data { autoindex on; } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ { expires max; access_log off; } 

您从OpenCart收到的网页中的URL由OpenCart软件生成。 您需要在其configuration中查找友好的URL,并启用这些URL。

然后,您可以在nginx中应用相应的rewrite规则,以便将传入的请求正确路由到OpenCart。

重写规则可以将传入的请求中的路由从一个很好的版本转换为一个基于index.php的咒语的版本,但是这听起来像这是一个关于在响应中发送的生成的HTML的问题,这仍然是用index.php咒语? 要在发送到浏览器的响应中更改基于index.php的路由,请尝试nginx'ngx_http_sub_module:

http://nginx.org/en/docs/http/ngx_http_sub_module.html

有些东西是:

 sub_filter '/index.php?route=' ''; sub_filter_once on; 

结合重写可能就足够了。

try_files指令应该处理大部分的工作。 我没有安装OpenCart,所以下面没有testing。 不过这可能是一个很好的起点。 $urivariables将包含一个前导/ ,这被我见过的.htaccess规则所排除。 如果是问题,可以多做一点工作。

 location = /sitemap.xml { try_files /index.php?route=feed/google_sitemap =404; } location = /googlebase.xml { try_files /index.php?route=feed/google_base =404; } try_files $uri $uri/ /index.php?_route_=$uri; 

以下看起来不错?

 map $arg_route $_dest { default "/"; "~*^(?:[^/]*)(?<dest>/.*)" $dest; } server { location / { try_files $uri @opencart; } location @opencart { rewrite ^(?i)/index.php$ $_dest? last; } } 

这可能会或可能不会工作,取决于您的上游Opencart认为它是多么“聪明”。

这个想法是,根据https://stackoverflow.com/questions/21687288/nginx-redirect-loop-remove-index-php-from-url/21813759#21813759 ,只有当index.php出现在原始发出redirect来自用户的请求(在$request_uri ),但是如果它仅仅作为内部路由的一部分存在(在$uri ),则不是。 例如,它可能看起来像下面的代码片段会导致循环,但它不应该。

 rewrite ^/([az]+/[az]+)$ /index.php?route=$1 last; if ($request_uri ~ ^/index.php?route=([az]+/[az]+)$) { return 301 /$1; } 

另外,如果你通过try_files进行的处理已经可以捕获404 ,并将其redirect到Opencart(例如,如果没有index.php?route=部分的URL已经按照你的意图工作),那么你需要的只是以下内容:

 if ($request_uri ~ ^/index.php?route=(.*)$) { return 301 $1; }