search

Home  >  Q&A  >  body text

Explained: Understanding mod_rewrite, URL rewriting, and creating "pretty links"

"Pretty links" is an often requested topic, but rarely fully explained. mod_rewrite is one way to make "pretty links", but it's complex, the syntax is very terse, hard to understand, and the documentation assumes some familiarity with HTTP. Can someone briefly explain how "pretty links" work and how to use mod_rewrite to create them?

Other common names, aliases, terms for clean URLs: RESTful URL, user-friendly URL, SEO-friendly URL, slugging and MVC URL (possibly a misnomer)

P粉501007768P粉501007768390 days ago751

reply all(2)I'll reply

  • P粉276064178

    P粉2760641782023-10-21 11:08:48

    To expand on deceze's answer, I'd like to provide some examples and an explanation of some other mod_rewrite features.

    All examples below assume that you have included RewriteEngine On in your .htaccess file.

    Rewrite example

    Let’s give an example:

    RewriteRule ^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$ /blog/index.php?id=&title= [NC,L,QSA]

    This rule is divided into 4 parts:

    1. RewriteRule - Start the rewrite rule
    2. ^blog/([0-9] )/([A-Za-z0-9-\ ] )/?$ - This is called a pattern, but I'll just call it For the left side of the rule - what you want to override
    3. blog/index.php?id=$1&title=$2 - called a replace, or the right side of the rewrite rule - the content you want to rewrite
    4. [NC,L,QSA] is the flag of the rewrite rule, separated by commas, I will explain it in detail later

    The above rewrite will allow you to link to something like /blog/1/foo/ and it will actually load /blog/index.php?id=1&title=foo .

    Left side of the rule

    • ^ represents the beginning of the page name - so it will rewrite example.com/blog/... but not example.com/foo/ blog/...
    • Each set of (…) brackets represents a regular expression, which we can capture as a variable on the right side of the rule. In this example:
      • The first set of brackets - ([0-9] ) - matches a string that is at least 1 character in length and contains only numeric values ​​(i.e. 0-9). This can be referenced by $1 on the right side of the rule
      • The second set of brackets matches a string that is at least 1 character in length and contains only alphanumeric characters (A-Z, a-z, or 0-9) or - or (note Escape with a backslash because if you don't escape it, this will appear as a regular expression repeating character ). This can be referenced by $2 on the right side of the rule
    • ? means that the preceding characters are optional, so in this example /blog/1/foo/ and /blog/1/foo code> will be rewritten to the same location
    • $ means this is the end of the string we want to match

    LOGO

    These options are added in square brackets at the end of the rewrite rule to specify certain conditions. Again, there are many different flags that you can read about in the documentation, but I'll cover some of the more common ones: < /a>

    NC
    The

    no case flag means that the rewrite rule is not case sensitive, so for the example rule above this means

    /blog/1/foo/ and /BLOG/1/foo / (or any variation thereof) will be matched.

    L

    The last flag indicates that this is the last rule that should be processed. This means that if and only if this rule matches, no further rules will be evaluated in the current rewrite processing run. If a rule does not match, all other rules will be tried as usual. If you do not set the

    L flag, all subsequent rules will apply to the rewritten URL.

    END

    Since Apache 2.4, you can also use the

    [END] flag. Rules matching this will completely terminate further aliasing/rewriting processing. (And the [L] flag usually triggers the second round, such as when rewriting a subdirectory or rewriting a subdirectory.)

    QSA

    The query string append flag allows us to pass additional variables to the specified URL, which will be added to the original get parameters. For our example, this means something like /blog/1/foo/?comments=15 will load /blog/index.php?id=1&title=foo&comments=15< /p>

    R

    This flag is not the one I used in the example above, but I thought it was worth mentioning. This allows you to specify an http redirect and optionally include a status code (e.g. R=301). For example, if you wanted to perform a 301 redirect on /myblog/ to /blog/, you would simply write a rule like this:

    RewriteRule ^/myblog/(*.)$ /blog/ [R=301,QSA,L]

    Rewrite conditions

    Override ConditionsMake overrides more powerful, allowing you to specify overrides for more specific situations. You can read more about it in the Documentation, but I'll cover some common examples and explain them:

    # 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]

    This is a very common practice and will add www. in front of your domain name (if it doesn't already exist) and perform a 301 redirect. For example, loading http://example.com/blog/ will redirect you to http://www.example.com/blog/

    # 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/ [L]

    This situation is slightly less common, but it is a good example of why the rule will not be executed if the filename is a directory or file that exists on the server.

    • %{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC] Only files with a file extension of jpg, jpeg, gif or png will be rewritten (uppercase or lowercase to be insensitive).
    • %{REQUEST_FILENAME} !-f Will check whether the file exists on the current server, and perform rewriting if it does not exist
    • %{REQUEST_FILENAME} !-d Will check whether the file exists on the current server, and perform rewriting if it does not exist
    • The rewrite will try to load the same file on another domain

    reply
    0
  • P粉022140576

    P粉0221405762023-10-21 00:43:03

    To understand what mod_rewrite is, you first need to understand how a web server works. The web server responded to HTTP request. The most basic level of HTTP request looks like this:

    GET /foo/bar.html HTTP/1.1

    This is a simple request from the browser to the web server for URL /foo/bar.html. It's important to emphasize that it doesn't request files, it just requests some arbitrary URL. The request might also look like this:

    GET /foo/bar?baz=42 HTTP/1.1

    This works just as well as a URL request, and is obviously file-agnostic.

    A web server is an application that listens on a port, accepts HTTP requests from that port and returns a response. The web server is completely free to respond to any request in any way it sees fit/to respond in any way you configure it to respond. This response is not a file, but an HTTP response, which may or may not have any relationship to any physical file on disk. The web server doesn't have to be Apache, there are many other web servers, they are just programs that run persistently and are attached to a port that responds to HTTP requests. You can write one yourself. The purpose of this paragraph is to get you past any notion that a URL is directly equivalent to a file, which is very important to understand. :)

    The default configuration of most web servers is to look for a file on the hard disk that matches a URL. If the server's document root is set to /var/www, it may look for the file /var/www/foo/bar.html if it exists. Provide it. If the file ends with ".php" it will call the PHP interpreter and return the result. All of these associations are fully configurable; the file does not have to end in ".php" for the web server to run the file through the PHP interpreter, and the URL does not have to match any specific file on disk for something to happen.

    mod_rewrite is a method of rewriting internal request processing. When the web server receives a request for the URL /foo/bar, you can rewrite that URL to something else, and the web server will look for a file on disk that matches it. Simple example:

    RewriteEngine On
    RewriteRule   /foo/bar /foo/baz

    This rule means As long as the request matches "/foo/bar", please rewrite it to "/foo/baz". The request will then be processed like /foo/baz<相反,已请求 /code>. This can be used for a variety of effects, such as:

    RewriteRule (.*) .html

    This rule matches anything (.*) and captures it ((..)), then rewrites it to append ".html" ". In other words, if /foo/bar is the requested URL, it will be processed as if /foo/bar.html had been requested. Regarding regex matching , capture, and replacement, see http://regular-expressions.info.

    Another often encountered rule is:

    RewriteRule (.*) index.php?url=

    This again matches anything and rewrites it to the file index.php, appending the originally requested URL in the url query parameter. That is, for any and all requests that come in, the file index.php will be executed, and that file will have access to the original request in $_GET['url'], so it can do whatever it wants Do things with it.

    First, you put these rewrite rules into your web server configuration file . Apache also allows *you to put them into a file named .htaccess in the document root (i.e. next to the .php file).

    * If the main Apache configuration file allows it; it is optional, but is usually enabled.

    mod_rewrite does nothing

    mod_rewrite won't magically make all URLs "pretty". This is a common misconception. If you have this link in your website:

    mod_rewrite can't make it pretty. In order to make it a beautiful link you must:

    1. Change the link to a beautiful link:

    2. Using any of the above methods, use mod_rewrite on the server to handle requests for the URL /my/pretty/link.

    (You can use mod_substitute< /a> in conjunction with transforming the outgoing HTML page and the links it contains. Although this is usually more laborious than just updating the HTML resource.)

    mod_rewrite can do a lot, and you can create very complex matching rules, including chaining multiple rewrites, proxying requests to completely different services or machines, returning specific HTTP status codes as responses, redirecting requests, etc. It is very powerful and can be very useful if you understand the basic HTTP request response mechanism. It doesn't automatically make your links pretty.

    Please see the official documentation for all possible flags and options.

    reply
    0
  • Cancelreply