3

在基于 Zend Framework 2 的网站(nginx 上的测试环境和 Apache 上的实时环境)上,有一个类别“课程”,其页面具有如下 URI:

domain.tld/courses/123-Name of course that can contain ®, €, (, ), and other special chars

课程名称来自数据库,并针对内部链接进行了 URL 编码:

domain.tld/courses/123-Name%20of%20course%20that%20can%20contain%20%C2%AE%2C%20%E2%82%AC%2C%20%C3%A4%2C%20(%2C%20)%2C%20and%20other%20special%20chars

它工作正常,但是当我尝试使用不编码的特殊字符访问页面时,会发生 404 错误。

使用空格字符的网站示例是维基百科。您可以使用

http://en.wikipedia.org/wiki/Signal_(electrical_engineering)

或者

http://en.wikipedia.org/wiki/Signal_%28electrical_engineering%29

并且总是得到你想要的页面。

有人知道如何实现这种行为(“à la Wikipedia”)吗?(也许使用 HTTP 重定向.htaccess规则?)


更新:

/etc/nginx/ax-common-vhost

server {
    listen   80;
    server_name
        foo.loc
        bar.loc
        baz.loc
    ;

    if ($host ~ ^(?<project>.+)\.(?<area>.+)\.loc$) {
        set $folder "$area/$project";
    }

    access_log /var/log/nginx/$area/$project.access.log;
    error_log /var/log/nginx/error.log;

    gzip on;
    gzip_min_length 1000;
    gzip_types text/plain text/xml application/xml;

    client_max_body_size 25m;

    root /var/www/$folder/public/;

    try_files $uri $uri/ /index.php?$args;
    index index.html index.php;

    location / {
        index index.html index.php;
    sendfile off;
    }

    location ~ (\.inc\.php|\.tpl|\.sql|\.tpl\.php|\.db)$ {
        deny all;
    }

    location ~ \.htaccess {
        deny all;
    }

    if (!-e $request_filename) {
        rewrite ^.*$ /index.php last;
    }

    location ~ \.php$ {
      fastcgi_cache        off;
      #fastcgi_pass        127.0.0.1:9001;
      fastcgi_pass         unix:/var/run/php5-fpm.sock;
      fastcgi_read_timeout 6000;
      fastcgi_index        index.php;
      include              fastcgi_params;
      fastcgi_param        SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param        APPLICATION_ENV development;
      fastcgi_param        HTTPS $https;
  }
}
4

2 回答 2

0

您可以通过在 .htaccess 文件中设置正确的重写规则来实现预期的 URL 重写行为。

我建议你看看rewriteflags,尤其是B 标志

于 2013-06-29T00:05:14.107 回答
0

您应该向我们展示您的 nginx fast_cgi 配置。

它们是为 PHP 设置PATH_INFO的几种方法,这是包含 ZF 必须管理的路径的字符串。

一种方法是:

fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;

这篇文章看来,您似乎也可以使用这种方式(命名为捕获)来避免 PATH_INFO 内容的所有 urlencoding:

location ~ ^(?<SCRIPT_FILENAME>.+\.php)(?<PATH_INFO>.+)$ {
(...)
fastcgi_param PATH_INFO $PATH_INFO;

因此,至少您会检测到问题是否来自于 urlencoding 过多或不足。

通过避免来自网络服务器的 urlencoding(以及对 apache 执行相同操作),您可以在 PHP 端管理路径的 urldecoding。因为这一次您知道它永远不会被 urldecoded,并且您必须在 php 中执行它 - 或者您可能必须对它进行 urlencode - 并且您必须管理路径可能出现在两个版本中的事实。

对于Zend Framework Router来说,这可能是一项不错的工作。路由器的工作之一是避免诸如 .htaccess 在 apache 中重写规则之类的事情,并以稳定且独立于 Web 服务器的方式管理应用程序中的 url。

第一步是测试路径字符串并检测是否需要进行 url 编码。当然,如果您在同一字符串中发送带有 url 编码和 url 解码字符混合的 url,事情会变得更加困难,因为您将无法决定(但对于网络服务器来说也是如此)。在您的示例中,您使用的括号不是在生成的编码 url 中编码而是在 wikipedia 示例中编码,您的应用程序必须为 rfc protected characters选择一个策略。

于 2013-07-01T13:21:08.153 回答