Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache 参考:mod_rewrite、URL rewriting和";“漂亮链接”;解释_Apache_.htaccess_Mod Rewrite_Friendly Url_Regex - Fatal编程技术网

Apache 参考:mod_rewrite、URL rewriting和";“漂亮链接”;解释

Apache 参考:mod_rewrite、URL rewriting和";“漂亮链接”;解释,apache,.htaccess,mod-rewrite,friendly-url,regex,Apache,.htaccess,Mod Rewrite,Friendly Url,Regex,“漂亮链接”是一个经常被要求的话题,但很少有人对它进行充分的解释。是制作“漂亮链接”的一种方法,但它很复杂,语法非常简洁,很难理解,并且文档假定对HTTP有一定的熟练程度。有人能简单地解释一下“漂亮链接”是如何工作的,以及如何使用mod_rewrite来创建它们吗 其他常用名称、别名、干净URL的术语:URL、用户友好URL、-友好URL和MVC URL(可能用词不当)要了解mod_rewrite是什么,首先需要了解web服务器是如何工作的。web服务器响应。最基本级别的HTTP请求如下所示:

“漂亮链接”是一个经常被要求的话题,但很少有人对它进行充分的解释。是制作“漂亮链接”的一种方法,但它很复杂,语法非常简洁,很难理解,并且文档假定对HTTP有一定的熟练程度。有人能简单地解释一下“漂亮链接”是如何工作的,以及如何使用mod_rewrite来创建它们吗


其他常用名称、别名、干净URL的术语:URL、用户友好URL、-友好URL和MVC URL(可能用词不当)

要了解mod_rewrite是什么,首先需要了解web服务器是如何工作的。web服务器响应。最基本级别的HTTP请求如下所示:

GET /foo/bar.html HTTP/1.1
GET /foo/bar?baz=42 HTTP/1.1
RewriteRule ^/myblog/(*.)$ /blog/$1 [R=301,QSA,L]
RewriteRule my-blog/entry.php?id=(\d+) my-blog/$1--i-found-the-answer [R]
这是一个浏览器向web服务器发出的简单请求,请求其提供URL
/foo/bar.html
。需要强调的是,它不请求文件,它只请求一些任意的URL。请求也可能如下所示:

GET /foo/bar.html HTTP/1.1
GET /foo/bar?baz=42 HTTP/1.1
RewriteRule ^/myblog/(*.)$ /blog/$1 [R=301,QSA,L]
RewriteRule my-blog/entry.php?id=(\d+) my-blog/$1--i-found-the-answer [R]
这和URL请求一样有效,更明显的是,它与文件无关

web服务器是一个侦听端口的应用程序,它接受来自该端口的HTTP请求并返回响应。web服务器完全可以自由地以其认为合适的任何方式响应任何请求/以您配置的任何方式响应。这个响应不是一个文件,它是一个HTTP响应,它可能与任何磁盘上的物理文件有关,也可能与之无关。web服务器不必是Apache,还有许多其他web服务器都是持久运行的程序,连接到响应HTTP请求的端口。你可以自己写一本。这一段的目的是让你不再认为URL直接等于文件,这一点理解起来非常重要。:)

大多数web服务器的默认配置是查找与硬盘上的URL匹配的文件。如果服务器的文档根设置为,比如说,
/var/www
,它可能会查看文件
/var/www/foo/bar.html
是否存在,如果存在,则为其提供服务。如果文件以“.php”结尾,它将调用php解释器,然后返回结果。所有这些关联都是完全可配置的;一个文件不必以“.php”结尾,web服务器就可以通过php解释器运行它,URL也不必匹配磁盘上的任何特定文件

mod_rewrite是重写内部请求处理的一种方法。当web服务器收到URL
/foo/bar
请求时,您可以在web服务器查找磁盘上与之匹配的文件之前将该URL重写为其他内容。简单的例子:

RewriteEngine On
RewriteRule   /foo/bar /foo/baz
此规则表示,只要请求与“/foo/bar”匹配,就将其重写为“/foo/baz”。然后,该请求将被处理为已被请求的
/foo/baz
。这可以用于各种效果,例如:

RewriteRule (.*) $1.html
此规则匹配任何内容(
*
)并捕获它(
(…)
),然后将其重写为追加“.html”。换句话说,如果
/foo/bar
是请求的URL,那么它将被当作请求了
/foo/bar.html
一样处理。有关正则表达式匹配、捕获和替换的详细信息,请参阅

另一个经常遇到的规则是:

RewriteRule (.*) index.php?url=$1
这同样会匹配任何内容并将其重写为index.php文件,原始请求的URL追加到
URL
query参数中。也就是说,对于任何和所有传入的请求,都会执行index.php文件,该文件将有权访问
$\u GET['url']
中的原始请求,因此它可以用它做任何事情

主要是将这些重写规则放入web服务器配置文件中。Apache还允许*您将它们放入文档根目录中名为
.htaccess
的文件中(即在.php文件旁边)

*如果主Apache配置文件允许;它是可选的,但通常是启用的

mod_重写没有做什么 mod_rewrite并不会神奇地让你所有的URL变得“漂亮”。这是一个常见的误解。如果您的网站中有此链接:

<a href="/my/ugly/link.php?is=not&amp;very=pretty">
结合转换传出的HTML页面及其包含的链接。虽然这通常比更新HTML资源更费劲。)

mod_rewrite可以做很多事情,您可以创建非常复杂的匹配规则,包括链接多个重写,将请求代理到完全不同的服务或机器,返回特定的HTTP状态码作为响应,重定向请求等。它非常强大,如果您了解基本的HTTP请求-响应机制,就可以很好地使用它。它不会自动让你的链接变得漂亮

有关所有可能的标志和选项,请参见。

要进一步展开,我想提供一些示例并解释一些其他mod_重写功能

以下所有示例都假设您已经在
.htaccess
文件中包含了
RewriteEngine On

重写示例 让我们举一个例子:

RewriteRule ^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$ /blog/index.php?id=$1&title=$2 [NC,L,QSA]
该规则分为4个部分:

# Apache 2.2
RewriteLogLevel 5
RewriteLog /tmp/rewrite.log

# Apache 2.4
LogLevel alert rewrite:trace5
#ErrorLog /tmp/rewrite.log
  • 重写规则
    -启动重写规则
  • ^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$
    -这称为模式,但我将其称为规则的左侧-您要从中重写的内容
  • blog/index.php?id=$1&title=$2
    -称为替换,或重写规则的右侧-您要重写的内容
  • [NC,L,QSA]
    是重写规则的标志,用逗号分隔,我将在后面详细解释
  • 上面的重写将允许您链接到类似于
    /blog/1/foo/
    的内容,它将实际加载
    /blog/index.php?id=1&title=foo

    规则的左边
    • ^
      指示页面名称的开头-因此它将重写
      example.com/blog/…
      ,但不会重写
      e
      
      # if the host doesn't start with www. then add it and redirect
      RewriteCond %{HTTP_HOST} !^www\.
      RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
      
      # if it cant find the image, try find the image on another domain
      RewriteCond %{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule (.*)$ http://www.example.com/$1 [L]
      
      http://example.com/script.php/virtual/path
      
      Options +MultiViews
      
      DefaultType application/x-httpd-php
      
      <Files article>
        SetHandler application/x-httpd-php
        # or SetType 
      </Files>
      
       RewriteRule ^contact$  templ/contact.html
       RewriteRule ^about$    about.php
      
       RewriteRule ^article/(\d+)$    article-show.php?id=$1
       #                      └───────────────────────────┘
      
       RewriteRule ^article/([\w-]+)$    article-show.php?title=$1
       #                       └────────────────────────────────┘
      
       RewriteRule ^article/(\d+)-([\w-]+)$    article.php?id=$1&title=$2
       #                      └───────────────────────────────┘
      
       #                               ┌─────────────────────────┐
       RewriteRule ^(blog|post|user)/(\w+)$  disp.php?type=$1&id=$2
       #               └───────────────────────────────────┘
      
       #                   ┌─────────────────────────────┐
       #                   │                 ┌───────────┼───────────────┐
       RewriteRule ^blog/(2009|2010|2011)/([\d-]+)/?$ old/blog.php?date=$2
       RewriteRule ^blog/(\d+)/([\d-]+)/?$  modern/blog/index.php?start=$2
       #                          └──────────────────────────────────────┘
      
       RewriteRule ^user-(\d+)$    show.php?what=user&id=$1
       #                   └──────────────────────────────┘
       # This could use `(\w+)` alternatively for user names instead of ids.
      
       RewriteRule ^wiki:(\w+):(\w+)$  wiki.php?sect=$1&page=$2 
       #                   └─────┼────────────────────┘       │
       #                         └────────────────────────────┘
      
       RewriteRule ^blog/([\w-]+)/?$  blog/show.php?id=$1
       #                         ┗┛
      
       Rewriterule ^(\w+)/?$                in.php?a=$1
       Rewriterule ^(\w+)/(\w+)/?$          in.php?a=$1&b=$2
       Rewriterule ^(\w+)/(\w+)/(\w+)/?$    in.php?a=$1&b=$2&c=$3
       #              └─────┴─────┴───────────────────┴────┴────┘
      
        RewriteRule ^(\w+)(?:/([^/]+))?/(\w+)$  ?main=$1&opt=$2&suffix=$3
      
       RewriteRule ^(specific)/prefix/(\d+)(/.*)?$  speci.php?id=$2&otherparams=$2
      
       RewriteRule  ^styles/([\w\.\-]+)\.css$  sass-cache.php?old_fn_base=$1
       RewriteRule  ^images/([\w\.\-]+)\.gif$  png-converter.php?load_from=$2
      
       # redirect browser for old/ugly incoming paths
       RewriteRule ^old/teams\.html$ /teams [R=301,QSA,END]
      
       # internally remap already-pretty incoming request
       RewriteRule ^teams$ teams.php        [QSA,END]
      
       RewriteRule  "^this [\w ]+/(.*)$"  "index.php?id=$1"  [L]
      
       RewriteCond %{REQUEST_URI} !-f
       RewriteCond %{REQUEST_URI} !-d
       RewriteRule ^.*$     index.php   [L]
      
       #                               ┌──────────┐
       RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]  │ 
       RewriteRule ^(.*)$ http://%1/$1 [R=301,L]  │
       #             ↓           └───┼────────────┘
       #             └───────────────┘
      
       RewriteCond %{SERVER_PORT} 80
       RewriteRule ^(.*)$ https://example.com/$1 [R,L]
      
       RewriteCond %{REQUEST_FILENAME}.php -f
       RewriteRule ^(.+)$  $1.php  [L]  # or [END]
      
       RewriteRule ^/article/\d+$  …
                    ↑
      
      <IfModule mod_rewrite.c>
         Rewrite… 
      </IfModule>
      
       RewriteCond %{SERVER_NAME} localhost
       RewriteRule ^secret  admin/tools.php
       RewriteRule ^hidden  sqladmin.cgi
      
       RewriteCond %{QUERY_STRING} \b(?:param)=([^&]+)(?:&|$)
       RewriteRule ^add/(.+)$  add/%1/$1  # ←──﹪₁──┘
      
      # Apache 2.2
      RewriteLogLevel 5
      RewriteLog /tmp/rewrite.log
      
      # Apache 2.4
      LogLevel alert rewrite:trace5
      #ErrorLog /tmp/rewrite.log
      
      [..] applying pattern '^test_.*$' to uri 'index.php'
      [..] strip per-dir prefix: /srv/www/vhosts/hc-profi/index.php -> index.php
      [..] applying pattern '^index\.php$' to uri 'index.php'
      
      RewriteRule my-blog/(\d+)--i-found-the-answer my-blog/entry.php?id=$1 
      
      RewriteRule my-blog/entry.php?id=(\d+) my-blog/$1--i-found-the-answer [R]
      
      RewriteRule my-blog/entry.php?id=(\d+) my-blog/i-found-the-answer [R]