Websites, finance, economy and my life.
标签类目:apache

FTP正常,WEB问题依旧

上午测试FTP还只有2k/s,刚才上传下载都已经稳定在100k左右,达到了学校无线内网FTP的速度。但是打开网页,不管是动态还是静态,问题依旧。

putty登陆,速度很快。重启过无数次apache了,问题依旧。重启mysql,无反应。重启服务器,mysql正常,apache正常,WEB问题依旧。

Google了一下,没找到相似情况。访问IDC网站,照样是蜗牛速度。真不知道问题出在哪儿了。

DH空间开通了,FTP上传10K不到,今后有得受了。

N久没到学校无线了,发现1G,2G的8个AP全部不能用,敏之正常,图书馆不稳定,在敏之102写了这篇日志。

Learn Apache mod_rewrite: 13 Real-world Examples

这篇文章真是写得太好了,所以忍不住就把它摘过来了,我一直坚持的原创风格也被打破了。不过为了尽量增加原创性,有时间我会将正文翻译的,我相信任何人看了都会大有帮助的。里面谈了RewriteRule和RewriteCond 的详细用法,还有301转向的使用方法,这是永久更换网址的最佳解决方案。正则规则也有提到,真是mod_rewrite的方方面面都有涉及,近期我还将 翻译一些关于其它网址SEO方法的文章,比如PATH_INFO,很好的解决了不支持.htaccess的虚拟主机用户SEO问题。好了,我们看正文吧:

Apache’s low-cost, powerful set of features make it the server of choice for organizations around the world. One of its most valuable treasures is the mod_rewrite module, the purpose of which is to rewrite a visitor’s request URI in the manner specified by a set of rules.

This article will lead you through rewrite rules, regular expressions, and rewrite conditions, and provide a great list of examples.

First off, I’m going to assume that you understand the common reasons for wanting a URI rewriting feature for your web site. If you’d like information about this field, there’s a good primer in the SitePoint article, mod_rewrite: A Beginner’s Guide to URL Rewriting. There, you’ll also find instructions on how to enable it on your own server.

Testing Your Server Setup

Some hosts do not have mod_rewrite enabled (by default it is not enabled). You can find out if your server has mod_rewrite enabled by creating a PHP script with one simple line of PHP code:

phpinfo();

If you load the script with a browser, look in the Apache Modules section. If mod_rewrite isn’t listed there, you’ll have to ask your host to enable it — or find a “good host”. Most hosts will have it enabled, so you’ll be good to go.

The Magic of mod_rewrite

Here’s a simple example for you: create three text files named test.html, test.php, and .htaccess.

In the test.html file, enter the following:

<h1>This is the HTML file.</h1>

In the test.php file, add this:

<h1>This is the PHP file.</h1>

Create the third file, .htaccess, with the following:

RewriteEngine on
RewriteRule ^/?test\.html$ test.php [L]

Upload all three files (in ASCII mode) to a directory on your server, and type:

http://www.example.com/path/to/test.html

into the location box — using your own domain and directory path of course! If the page shows “This is the PHP file”, it’s working properly! If it shows “This is the HTML file,” something’s gone wrong.

If your test worked, you’ll notice that the test.html URI has remained in the browser’s location box, yet we’ve seen the contents of the test.php file. You’ve just witnessed the magic of mod_rewrite!

mod-rewrite Regular Expressions

Now we can begin rewriting your URIs! Let’s imagine we have a web site that displays city information. The city is selected via the URI like this:

http://www.example.com/display.php?country=USA&state=California&city=San_Diego

Our problem is that this is way too long an unfriendly to users. We’d much prefer it if visitors could use:

http://www.example.com/USA/California/San_Diego

We need to be able to tell Apache to rewrite the latter URI into the former. In order for the display.php script to read and parse the query string, we’ll need to use regular expressions to tell mod_rewrite how to match the two URIs. If you’re not familiar with regular expressions (regex), many sites provide excellent tutorials. At the end of this article, I’ve listed the best pages I’ve found on the topic. If you’re not able to follow my explanations, I recommend reviewing the first two of those links.

A very common approach is to use the expression (.*). This expression combines two metacharacters: the dot character, which means ANY character, and the asterisk character, which specifies zero or more of the preceding character. Thus, (.*) matches everything in the {REQUEST_URI} string. {REQUEST_URI} is that part of the URI which follows the domain up to but not including the ? character of a query string, and is the only Apache variable that a rewrite rule attempts to match.

Wrapping the expression in brackets stores it in an “atom,” which is a variable that allows the matched characters to be reused within the rule. Thus, the expression above would store USA/California/San_Diego in the atom. To solve our problem, we’d need three of these atoms, separated by the subdirectory slashes (/), so the regex would become:

(.*)/(.*)/(.*)

Given the above expression, the regex engine will match (and save) three values separated by two slashes anywhere in the {REQUEST_URI} string. To solve our specific problem, though, we’ll need to restrict this somewhat — after all, the first and last atoms above could match anything!

To begin with, we can add the start and end anchor characters. The ^ character matches matching characters at the start of a string, and the $ character matches characters at the end of a string.

^(.*)/(.*)/(.*)$

This expression specifies that the whole string must be matched by our regex; there cannot be anything else before or after it.

However, this approach still allows too many matches. We’re storing our matches as atoms, and will be passing them to a query string, so we have to be able to trust what we match. Matching anything with (.*) is too much of a potential security hazard, and, when used inappropriately, could even cause mod_rewrite to get stuck in a loop!

To avoid unnecessary problems, let’s change the atoms to specify precisely the characters that we will allow. Because the atoms represent location names, we should limit the matched characters to upper and lowercase letters from A to Z, and because we use it to represent spaces in the name, the underscore character (_) should also be allowed. We specify a set using square brackets, and a range using the - character. So the set of allowed characters is written as [a-zA-Z_]. And because we want to avoid matching blank names, we add the + metacharacter, which specifies a match only on one or more of the preceding character. Thus, our regex is now:

^([a-zA-Z_]+)/([a-zA-Z_]+)/([a-zA-Z_]+)$

The {REQUEST_URI} string starts with a / character. Apache changed regex engines when it changed versions, so Apache version 1 requires the leading slash while Apache 2 forbids it! We can satisfy both versions by making the leading slash optional with the expression ^/? (? is the metacharacter for zero or one of the preceding character). So now we have:

^/?([a-zA-Z_]+)/([a-zA-Z_]+)/([a-zA-Z_]+)$

With regex in hand, we can now map the atoms to the query string:

display.php?country=$1&state=$2&city=$3

$1 is the first (country) atom, $2 is the second (state) atom and $3 is the third (city) atom. Note that there can only be nine atoms created, in the order in which the opening brackets appear — $1 ... $9 in a regular expression.

We’re almost there! Create a new .htaccess file with the text:

RewriteRule ^/?([a-zA-Z_]+)/([a-zA-Z_]+)/([a-zA-Z_]+)$ display.php?country=$1&state=$2&city=$3 [L]

Save this to the directory in which display.php resides. The rewrite rule must go on one line with one space between the RewriteRule statement, the regex, and the redirection (and before any optional flags). We’ve used the [L], or ‘last’ flag, which is the terminating flag (more on flags later).

Our rewrite rule is now complete! The atom values are being extracted from the request string and added to the query string of our rewritten URI. The display.php script will likely extract these values from the query string and use them in a database query or something similar.

If, however, you have only a short list of allowable countries, it might be best to avoid potential database problems by specifying the acceptable values within the regex. Here’s an example:

^/?(USA|Canada|Mexico)/([a-zA-Z_]+)/([a-zA-Z_]+)$

If you’re concerned about capitalization because the values in your database are strictly lowercase, you can make the regex engine ignore the case by adding the No Case flag, [NC], after the rewritten URI. Just don’t forget to convert the values to lowercase in your script after you obtain the $_GET array.

If you want to use numbers (0, 1, … 9) for, say, Congressional Districts, then you’ll need to change an atom’s specification from ([a-zA-Z_]+) to ([0-9]) to match a single digit, ([0-9]{1,2}) to match one or two digits (0 through 99), or ([0-9]+) for one or more digits, which is useful for database IDs.

The RewriteCond Statement

Now that you’ve learned how to use mod_rewrite’s basic RewriteRule statement with the {REQUEST_URI} string, it’s time to see how we can use conditionals to access other variables with the RewriteCond statement. The RewriteCond statement is used to specify the conditions under which a RewriteRule statement should be applied.

RewriteCond is similar in format to RewriteRule in that you have the command name, RewriteCond, a variable to be matched, the regex, and flags. The logical OR flag, [OR], is a useful flag to remember because all RewriteCond and RewriteRule statements are inclusive, in the sense of a logical AND relationship, until terminated by the Last, [L], flag.

You can test many server variables with a RewriteCond statement. You can find a list in the SitePoint article I mentioned previously, but this is the best list of server variables I’ve found.

As an example, let’s assume that we want to force the www in your domain name. To do this, you’ll need to test the Apache {HTTP_HOST} variable to see if the www. is already there and, if it’s not, redirect to the desired host name:

RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule .? http://www.example.com%{REQUEST_URI} [R=301,L]

Here, to denote that {HTTP_HOST} is an Apache variable, we must prepend a % character to it. The regex begins with the ! character, which will cause the condition to be true if it doesn’t match the pattern. We also have to escape the dot character so that it matches a literal dot and not any character, as is the case with the dot metacharacter. We’ve also added the No Case flag to make this operation case-insensitive.

The RewriteRule will match zero or one of any character, and will redirect to http://www.example.com plus the original {REQUEST_URI} value. The R=301, or redirect, flag will cause Apache to issue a HTTP 301 response, which indicates that this is a permanent redirection; the Last flag tells mod_rewrite that you’ve completed this block statement.

RewriteCond statements can also create atoms, but these are denoted with %1 ... %9 in the same way that RewriteRule atoms are denoted with $1 ... $9. You’ll see these atom variables in operation in the examples later on.

mod_rewrite Flags

mod_rewrite uses “flags” to give our rewrite conditions and rules additional features. We add flags at the end of a condition or rule using square brackets, and separate multiple flags with a comma. The main flags with which you’ll need to be familiar are:

  • last|L – The Last flag tells Apache to terminate a series of rewrite conditions and rewrite rules in the same way that } will terminate a statement block in PHP. Note that this flag does not terminate mod_rewrite processing!
  • nocase|NC – The No Case flag tells Apache to ignore the case of the string in the regex and is often necessary when writing a RewriteCond statement that matches the {HTTP_HOST} variable for a domain name, which is not case sensitive.
  • redirect|R – The Redirect flag is used to trigger an external (visible) redirection. By default, this means that Apache will issue an HTTP 302 response to indicate that the document has been moved temporarily, but you can specify the HTTP code if you like. For example, you could use [R=301] to make Apache issue a HTTP 301 response (moved permanently), which is often useful if you need search engines to reindex a changed URI.
  • qsappend|QSA – The Query String Appended flag is used to “pass through” existing query strings. You can also define a new query sting to which the old string will be appended, just be careful not to replicate key names. Failure to use the QSA flag will cause the creation of a query string during a redirection to destroy an existing query string.
  • forbidden|F – The Forbidden flag is used to tell Apache when not to provide a page in response to a request. As a result, Apache will issue a HTTP 403 response, which can be used to protect files from being viewed by unauthorized visitors, bandwidth leeches, and so on.
  • ornext|OR – The OR flag allows you to combine rewrite conditions with a logical OR relationship as opposed to the default AND.
  • next|N – The Next flag tells mod_rewrite to restart the rewriting process from the first rule, but to use the URI that was returned from the last processed rewrite rule. This is useful for replacing characters in the {REQUEST_URI} when you don’t know how many there will be.

You can read about the other available flags at Apache.org’s mod_rewrite documentation page.

mod_rewrite Comments

The RewriteEngine on statement is needed at the start of any mod_rewrite code, but it is also useful in another role. As a good programmer, you know how important comments are in your code. mod_rewrite allows you to comment out an entire block of mod_rewrite code by wrapping the code in RewriteEngine off and RewriteEngine on statements:

RewriteEngine off
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule .? http://www.example.com%{REQUEST_URI} [R=301,L]
RewriteEngine on

None of the statements above will be read by the mod_rewrite engine. RewriteEngine statements can be very helpful when developing new mod_rewrite code — just use them as you would the /* ... */ wrapper for PHP comments.

mod_rewrite Tips

As a webmaster, it’s up to you to determine how your pages will be identified to visitors, as well as how to rewrite those URIs so that Apache can serve the appropriate content. Be sure to put some careful consideration into the creation of your new URI scheme. And don’t forget that after implementing your new URI scheme, you may have to go back over old content, updating existing links to match the new scheme.

When you design your new URI scheme, make use of unique keys whenever you can. In a previous example, I used countries, states and cities as keys — items that would be unique in a database. But as I build web sites for clients to update themselves, it’s unreasonable for me to insist that they provide unique titles for all their articles. Articles in the database are typically identified by an auto-incremented ID, which would be perfect for my friendly URI scheme. It makes your rewrite rules a lot simpler because you can map a URI atom to a query string value directly.

People often attempt to use a database to redirect from a title or other such field to a specific ID value. mod_rewrite has a RewriteMap statement for this purpose, but you need to have access to your Apache main configuration file: httpd.conf. Typically, you’ll only have access to this file if you own and operate the server. Instead, avoid the problem completely, and use the ID field to create your links.

Remember that spaces appear as %20 in URIs, so you’ll need to replace them in your PHP code. PHP’s str_replace function is perfect for this task. Generally, we need to replace spaces with %20 when generating links, and convert %20 back to spaces when reading in query string values from the $_GET array. However, when working with unique database field values that contain spaces, I prefer to use the underscore character to replace the spaces in resulting links. To do so, you can use the following PHP code:

$name = str_replace ( ' ', '_', $name );

Be careful not to break existing relative links when you implement your new URI scheme. Developers are often surprised when suddenly their CSS, JavaScript files, and images cease to work. Remember that relative links are relative to the current URI at the browser end — that’s the requested URI, not the rewritten one. Depending on your site’s configuration, you may need to use absolute URIs, or the HTML <base> tag, for all your static resources.

13 mod_rewrite Examples

Earlier, we looked at an example that forced the inclusion of the www part of a domain name for every request. Let’s have a look at some more examples and see how useful mod_rewrite can be.

1. Forcing www for a domain while preserving subdomains

RewriteCond %{HTTP_HOST} ^([a-z.]+)?example\.com$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .? http://www.%1example.com%{REQUEST_URI} [R=301,L]

This rule captures the optional subdomain using the %1 variable, and, if it doesn’t start with www., redirects with www. prepended to the subdomain. The domain and the original {REQUEST_URI} are appended to the result.

2. Eliminating www from a domain

RewriteCond %{HTTP_HOST} !^example\.com$ [NC]
RewriteRule .? http://example.com%{REQUEST_URI} [R=301,L]

3. Getting rid of the www but preserving a subdomain

RewriteCond %{HTTP_HOST} ^www\.(([a-z0-9_]+\.)?example\.com)$ [NC]
RewriteRule .? http://%1%{REQUEST_URI} [R=301,L]

Here, the subdomain is captured in %2 (the inner atom) but, since it’s optional and already captured in the %1 variable, all you need is the %1 for the subdomain.

4. Preventing image hotlinking

If some unscrupulous webmasters are leeching your bandwidth by linking to images from your site to post on theirs, you can use the following rule to block the requests:

RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?example\.com/ [NC]
RewriteRule \.(gif|jpg|png)$ - [F]

If the {HTTP_REFERER} value is not blank, or from your own domain (example.com), this rule will block the viewing of URIs ending in .gif, .jpg, or .png using the forbidden flag, F.

If you are upset enough at these hotlinkers, you could change the image and let visitors to the site know that you know that they’re hotlinking:

RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?example\.com/.*$ [NC]
RewriteRule \.(gif|jpg|png)$ http://www.example.com/hotlinked.gif [R=301,L]

Instead of blocking the URI, the above rule rewrites it to a specific image in our domain. What appears in this image is completely up to your imagination!

You can block specific domains using:

RewriteCond %{HTTP_REFERER} !^http://(www\.)?leech_site\.com/ [NC]
RewriteRule \.(gif|jpg|png)$ - [F,L]

This rule blocks all requests where the {HTTP_REFERER} field is set to the bad domain.

Of course, the above rules rely on the {HTTP_REFERER} value being set correctly. It usually is, but if you’d rather rely on the IP Address, use {REMOTE_ADDR} instead.

5. Redirecting to a 404 page if the directory and file do not exist

If your host doesn’t provide for a “file not found” redirection, create it yourself!

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .? /404.php [L]

Here, -f matches an existing filename and -d matches an existing directory name. This script checks to see that the requested filename is not an existing filename or directory name before it redirects to the 404.php script. You can extend this script: include the URI in a query string by adding ?url=$1 immediately after the URI:

RewriteRule ^/?(.*)$ /404.php?url=$1 [L]

This way, your 404.php script can do something with the requested URL: display it in a message, send it in an email alert, perform a search, and so on.

6. Renaming your directories

If you’ve shifted files around on your site, changing directory names, try this:

RewriteRule ^/?old_directory/([a-z/.]+)$ new_directory/$1 [R=301,L]

I’ve included the literal dot character (not the “any character” metacharacter) inside the set to allow file extensions.

7. Converting old .html links to new .php links

Updating your web site but need to be sure that bookmarked links will still work?

RewriteRule ^/?([a-z/]+)\.html$ $1.php [L]

This is not a redirection, so it will be invisible to your visitors. To make it permanent (and visible), change the flag to [R=301,L].

8. Creating extensionless links

If your site uses PHP files, and you want to make your links easier to remember — or you just want to hide the file extension, try this:

RewriteRule ^/?([a-z]+)$ $1.php [L]

If you have a mixture of both .html and .php files, you can use RewriteCond statements to check whether the filename with either extension exists as a file:

RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.php [L]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.html [L]

If the file name exists with the .php extension, that rule will be chosen.

9. Checking for a key in a query string

If you need to have a specific key’s value in your query string, you can check for its existence with a RewriteCond statement:

RewriteCond %{QUERY_STRING} !uniquekey=
RewriteRule ^/?script_that_requires_uniquekey\.php$ other_script.php [QSA,L]

The above code will check the {QUERY_STRING} variable for a lack of the key uniquekey and, if the {REQUEST_URI} is the script_that_requires_uniquekey, it will redirect to an alternative URI.

10. Deleting the query string

Apache’s mod_rewrite automatically passes through a query string unless you do either of the following:

  • Assign a new query string (you can keep the original query string by adding a QSA flag, e.g., [QSA,L]).
  • Add a ? after a filename (for example, index.php?). The ? will not be shown in the browser’s location field.

11. Redirecting a working URI to a new format

Here’s a curly one. Let’s say, for example, that we’ve got a set of working URLs that look like this: /index.php?id=nnnn. However, we’d really like to change them to /nnnn and make sure search engines update their indexes to the new URI format. First, we’d have to redirect the old URIs to the new ones so that search engines update their indexes, but we’d still have to rewrite the new URI back to the old one so that the index.php script would run. Have I got your head spinning?

The trick here is to place into the query string a marker code that will not be seen by visitors. We redirect from the old link to the new format only if the “marker” is not present in the query string. Then we rewrite the new format link back to the old format, and add a marker to the query string, using the QSA flag to ensure we’re not eliminating an existing query string. Here’s how it’s done:

RewriteCond %{QUERY_STRING} !marker
RewriteCond %{QUERY_STRING} id=([-a-zA-Z0-9_+]+)
RewriteRule ^/?index\.php$ %1? [R=301,L]

RewriteRule ^/?([-a-zA-Z0-9_+]+)$ index.php?marker&id=$1 [L]

Here, the original URI, http://www.example.com/index.php?id=nnnn, does not contain the marker, so it’s redirected by the first rule to http://www.example.com/nnnn with a HTTP 301 response. The second rule rewrites http://www.example.com/nnnn back to http://www.example.com/index.php?marker&id=nnnn, adding marker and id=nnnn in a new query string; then, the mod_rewrite process is started over.

In the second iteration, the marker is matched so the first rule is ignored and, since there’s a dot character in index.php?marker&id=nnnn, the second rule is also ignored … and we’re finished!

Note that, while useful, this solution does require additional processing by Apache, so be careful if you’re using it on shared servers with a lot of traffic.

12. Ensuring that a secure server is used

Apache can determine whether you’re using a secure server in two ways: using the {HTTPS}, or {SERVER_PORT}, variables:

RewriteCond %{REQUEST_URI} ^secure_page\.php$
RewriteCond %{HTTPS} !on
RewriteRule ^/?(secure_page\.php)$ https://www.example.com/$1 [R=301,L]

The above example tests that the {REQUEST_URI} value is equal to our secure page script, and that the {HTTPS} value is not equal to on. If both these conditions re met, the request is redirected to the secure server URI. Alternatively, you could do the same thing by testing the {server_port} value, where 443 is typically the secure server port:

RewriteCond %{REQUEST_URI} ^secure_page\.php$
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/?(secure_page\.php)$ https://www.example.com/$1 [R=301,L]

13. Enforcing secure server only on selected pages

In situations where secure and unsecured domains share the web server’s DocumentRoot directory, you’ll need a RewriteCond statement to check that the secure server port isn’t being used, and then only redirect the request if the requested script is one in the list of those that require a secure server:

RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/?(page1|page2|page3|page4|page5)$  https://www.example.com/%1 [R=301,L]

Here’s how you’d redirect requests for pages not requiring a secure server back to port 80:

RewriteCond %{ SERVER_PORT } ^443$
RewriteRule !^/?(page6|page7|page8|page9)$ http://www.example.com%{REQUEST_URI} [R=301,L]

Summary

Apache mod_rewrite is primarily used to allow SEO and user friendly URIs, but it’s also an extremely flexible tool for other important redirection tasks. If you want to learn more, here are some very useful resources I’ve found:

Regular Expressions

mod_rewrite

.htaccess使用指南

Apache服务器的.htaccess是一个非常强大的分布式配置文件,学会使用.htaccess,对虚拟主机用户来说,可以实现众多的功能。这里有一篇很容易理解的.htaccess介绍,作为入门文章非常的适合。文章最初来自freewebmasterhelp.com,QiRan作了简单的中文翻译,我将加以完善。

Part 1 – 介绍
Part 2 – .htaccess命令
Part 3 – 密码保护
Part 1 – 介绍

介绍
从本指南中,你将可以学习到有关.htaccess文件及其功能的知识,并用以优化你的网站。尽管.htaccess只是一个文件,但它可以更改服务器的设置,允许你做许多不同的事情,最流行的功能是您可以创建自定义的“404 error”页面。.htaccess并不难于使用,归根结底,它只是在一个text文档中添加几条简单的指令而已。
我的主机支持它吗?

这可能很难用简单的答案来回答。许多主机支持.htaccess,但实际上并不会特别声明,许多其他类型的主机有能力但并不允许他们的用户使用.htaccess。一般来说,如果你的主机使用Unix或Linux系统,或任何版本的Apache网络服务器,从理论上都是支持.htaccess的,尽管你的主机服务商可能不允许你使用它。

判断你的主机是否允许.htaccess,一个标志很好的是它是否支持文件夹密码保护。为达到此功能,主机服务商需要使用.htaccess(当然,少数情况下他们虽提供密码保护功能,但却并不允许你使用.htaccess)。如果你不确定自己的主机是否支持.htaccess,最好的办法是上传你自己的.htaccess文件看看是否有用,或者直接发送邮件向你的主机服务商咨询。

我该怎么做?
你可能疑惑.htaccess到底能做些什么,或者你可能曾知道它的一些功能但并不真正了解你实际到底可以用它来做多少事情。

.htaccess可以做大量的事情,包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件。

创建一个.htaccess文档
创建.htaccess文件也许会给你带来一些困难。写文件很容易,你只需要在文字编缉器(例如:写字板)里写下适当的代码。真正困难的可能是文件的保存,因为.htaccess是一个古怪的文件名(它事实上没有文件名,只有一个由8个字母组成的扩展名),而在一些系统(如Windows 3.1)中无法接受这样的文件名。在大多数的操作系统中,你需要做的是将文档保存成名为:“.htaccess”(包括引号)。如果这也不行,你需要将其先命名为其它名字(例如htaccess.txt),再将其上传到服务器上,之后直接使用FTP软件来重命名。

警告
在使用.htaccess之前,我必须给你一些警告。虽然在服务器上使用.htaccess绝对不太可能给你带来任何麻烦(如果有些东西错了,它只是没效用罢了),但如果你使用Microsoft FrontPage Extensions,就必须特别小心。因为FrontPage Extensions本身使用了.htaccess,因此你不能编辑它并加入你自己的信息。如果确实有这方面的需要(并不推荐,但是可能),你应该先从服务器上下载.htaccess文档(如果存在),之后在前面加上你的代码。

自定义错误页
我要介绍的.htaccess的第一个应用是自定义错误页面,这将使你可以拥有自己的、个性化的错误页面(例如找不到文件时),而不是你的服务商提供的错 误页或没有任何页面。这会让你的网站在出错的时候看上去更专业。你还可以利用脚本程序在发生错误的时候通知你(例如我使用Free Webmaster Help的PHP脚本程序,当找不到页面的时候自动Email给我)。
你所知道的任何页面错误代码(像404找不到页面),都可以通过在.htaccess文件里加入下面的文字将其变成自定义页面:
ErrorDocument errornumber /file.html
举例来说,如果我的根目录下有一个notfound.html文件,我想使用它作为404 error的页面:
ErrorDocument 404 /notfound.html
如果文件不在网站的根目录下,你只需要把路径设置为:
ErrorDocument 500 /errorpages/500.html
以下是一些最常用的错误:
401 – Authorization Required 需要验证
400 – Bad request 错误请求
403 – Forbidden 禁止
500 – Internal Server Error 内部服务器错误
404 – Wrong page 找不到页面
接下来,你要做的只是创建一个错误发生时显示的文件,然后把它们和.htaccess一起上传。

Part 2 – .htaccess命令
介绍
在上一部分,我已经简单介绍了.htaccess以及它的一些有用功能,在这一部分,我将向你演示如何使用.htaccess文档去实现这些功能。
停示显示目录列表
有些时候,由于某种原因,你的目录里没有index文件,这意味着当有人在浏览器地址栏键入了该目录的路径,该目录下所有的文件都会显示出来,这会给你的网站留下安全隐患。
为避免这种情况(而不必创建一堆的新index文件),你可以在你的.htaccess文档中键入以下命令,用以阻止

目录列表的显示:
Options -Indexes

阻止/允许特定的IP地址
某些情况下,你可能只想允许某些特定IP的用户可以访问你的网站(例如:只允许使用特定ISP的用户进入某个目录),或者想封禁某些特定的IP地址(例如:将低级用户隔离于你的信息版面外)。当然,这只在你知道你想拦截的IP地址时才有用,然而现在网上的大多数用户都使用动态IP地址,所以这并不是限制使用的常用方法。
你可以使用以下命令封禁一个IP地址:
deny from 000.000.000.000
这里的000.000.000.000是被封禁的IP地址,如果你只指明了其中的几个,则可以封禁整个网段的地址。如你输入210.10.56.,则将封禁210.10.56.0~210.10.56.255的所有IP地址。
你可以使用以下命令允许一个IP地址访问网站:
allow from 000.000.000.000
被允许的IP地址则为000.000.000.000,你可以象封禁IP地址一样允许整个网段。
如果你想阻止所有人访问该目录,则可以使用:
deny from all
不过这并不影响脚本程序使用这个目录下的文档。

替换index文件
也许你不想一直使用index.htm或index.html作为目录的索引文件。举例来说,如果你的站点使用PHP文件,你可能会想使用 index.php来作为该目录的索引文档。当然也不必局限于“index”文档,如果你愿意,使用.htaccess你甚至能够设置foofoo.balh来作为你的索引文档!
这些互为替换的索引文件可以排成一个列表,服务器会从左至右进行寻找,检查哪个文档在真实的目录中存在。如果一个也找不到,它将会把目录列表显示出来(除非你已经关闭了显示目录文件列表)。
DirectoryIndex index.php index.php3 messagebrd.pl index.html index.htm
重定向
.htaccess最有用的功能之一就是将请求重定向到同站内或站外的不同文档。这在你改变了一个文件名称,但仍然想让用户用旧地址访问到它时,变的极为有用。另一个应用(我发现的很有用的)是重定向到一个长URL,例如在我的时事通讯中,我可以使用一个很简短的URL来指向我的会员链接。以下是一个重定向文件的例子:
Redirect /location/from/root/file.ext http://www.othersite.com/new/file/location.xyz
上述例子中,访问在root目录下的名为oldfile.html可以键入:
/oldfile.html
访问一个旧次级目录中的文件可以键入:
/old/oldfile.html
你也可以使用.htaccess重定向整个网站的目录。假如你的网站上有一个名为olddirectory的目录,并且你已经在一个新网站http://www.newsite.com/newdirectory/上建立了与上相同的文档,你可以将旧目录下所有的文件做一次重定向而不必一一声明:
Redirect /olddirectory http://www.newsite.com/newdirectory
这样,任何指向到站点中/olddirectory目录的请求都将被重新指向新的站点,包括附加的额外URL信息。例如有人键入:

http://www.youroldsite.com/olddirecotry/oldfiles/images/image.gif

请求将被重定向到:

http://www.newsite.com/newdirectory/oldfiles/images/image.gif

如果正确使用,此功能将极其强大。

Part 3 – 密码保护
Introduction 介绍
尽管有各种各样的.htaccess用法,但至今最流行的也可能是最有用的做法是将其用于网站目录可靠的密码保护。尽管JavaScript等也能做到,但只有.htaccess具有完美的安全性(即访问者必须知晓密码才可以访问目录,并且绝无“后门”可走)。
密码保护的.htaccess文件
利用.htaccess将一个目录加上密码保护分两个步骤。第一步是在你的.htaccess文档里加上适当的几行代码,再将.htaccess文档放进你要保护的目录下:
AuthName “Section Name”
AuthType Basic
AuthUserFile /full/path/to/.htpasswd
Require valid-user
你可能需要根据你的网站情况修改一下上述内容中的一些部分,如用被保护部分的名字”Members Area”,替换掉“Section Name”。
/full/parth/to/.htpasswd则应该替换为指向.htpasswd文件(后面详述该文档)的完整服务器路径。如果你不知道你网站空间的完整路径,请询问一下你的系统管理员。
密码保护的.htpasswd文件
目录的密码保护比.htaccess的其他功能要麻烦些,因为你必须同时创建一个包含用户名和密码的文档,用于访问你的网站,相关信息(默认)位于一个名为.htpasswd的文档里。像.htaccess一样,.htpasswd也是一个没有文件名且具有8位扩展名的文档,可以放置在你网站里的任何地方(此时密码应加密),但建议你将其保存在网站Web根目录外,这样通过网络就无法访问到它了。
输入用户名和密码
创建好.htpasswd文档后(可以通过文字编辑器创建),下一步是输入用于访问网站的用户名和密码,应为:
username:password
“password”的位置应该是加密过的密码。你可以通过几种方法来得到加密过的密码:一是使用一个网上提供的permade脚本或自己写一个;另一个很不错的username/password加密服务是通过KxS网站,这里允许你输入用户名及密码,然后生成正确格式的密码。
对于多用户,你只需要在.htpasswd文档中新增同样格式的一行即可。另外还有一些免费的脚本程序可以方便地管理.htpasswd文档,可以自动新增/移除用户等。
访问网站
当你试图访问被.htaccess密码保护的目录时,你的浏览器会弹出标准的username/password对话窗口。如果你不喜欢这种方式,有些脚本程序可以允许你在页面内嵌入username/password输入框来进行认证,你也可以在浏览器的URL框内以以下方式输入用户名和密码(未加密 的):

http://username:password@www.website.com/directory/

小结
.htaccess是一个站点管理员可以应用的强大工具,有更多的变化以适应不同的用途,可以节约时间及提高网站的安全性。
相关阅读:
KxS Password Encrypter
Apache .htaccess Documentation
More .htaccess Sites
Related Reading
.htaccess的特别说明
启用.htaccess,需要修改httpd.conf,启用AllowOverride,并可以用AllowOverride限制特定命令的使用
如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。例如,需要使用.config ,则可以在服务器配置文件中按以下方法配置:
AccessFileName .config
一般情况下,不应该使用.htaccess文件,除非你对主配置文件没有访问权限。有一种很常见的误解,认为用户认证只能通过.htaccess文件实现,其实并不是这样,把用户 认证写在主配置文件中是完全可行的,而且是一种很好的方法。.htaccess文件应该被用在内容提供者需要针对特定目录改变服务器的配置而又没有root权限的情况下。如果服务器管理员不愿意频繁修改配置,则可以允许用户通过.htaccess文件自己修改配置,尤其是ISP在同一个机器上运行了多个用户站点,而又希望用户可以自己改变配置的情况下。虽然如此,一般都应该尽可能地避免使用.htaccess文件。任何希望放在.htaccess文件中的配置,都可以放在主配置文件的段中,而且更高效。避免使用.htaccess文件有两个主要原因,即性能和安全。

Apache虚拟主机静态化规则改独立主机rewrite规则

如果开启.htaccess查找功能会影响系统速度,所以自从搭建服务器后都没有打开这个功能。加上discuz和phpwind都是推荐直接在httpd.conf中加的,所以一直都没去动过这个。
但前几天装phpbb的那个url优化mod,竟然没提供独立主机的规则,之后装Sablog-X也没有提供。呵呵,就想到自己改了,其实discuz提供了很好的教程,自己把两种规则一对照,规律一下子就出来了,下面简单来说说吧,先把discuz 6.0的两种规则列出来:

Apache虚拟主机rewrite规则:

# 将 RewriteEngine 模式打开
RewriteEngine On
# 修改以下语句中的 /discuz 为你的论坛目录地址,如果程序放在根目录中,请将 /discuz 修改为 /
RewriteBase /discuz
# Rewrite 系统规则请勿修改
RewriteRule ^archiver/((fid|tid)-[0-9]+\.html)$ archiver/index.php?$1
RewriteRule ^forum-([0-9]+)-([0-9]+)\.html$ forumdisplay.php?fid=$1&page=$2
RewriteRule ^thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ viewthread.php?tid=$1&extra=page\%3D$3&page=$2
RewriteRule ^space-(username|uid)-(.+)\.html$ space.php?$1=$2
RewriteRule ^tag-(.+)\.html$ tag.php?name=$1

Apache独立主机rewrite规则:

RewriteEngine On
RewriteRule ^(.*)/archiver/((fid|tid)-[0-9]+\.html)$ $1/archiver/index.php?$2
RewriteRule ^(.*)/forum-([0-9]+)-([0-9]+)\.html$ $1/forumdisplay.php?fid=$2&page=$3
RewriteRule ^(.*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/viewthread.php?tid=$2&extra=page\%3D$4&page=$3
RewriteRule ^(.*)/space-(username|uid)-(.+)\.html$ $1/space.php?$2=$3
RewriteRule ^(.*)/tag-(.+)\.html$ $1/tag.php?name=$2

两者对比,不难发现,之间有三处区别:
1、独立主机每条规则以^(.*)开头,而虚拟主机就是^,所以加入(.*)就行了;
2、独立主机规则的后半段以$1/开头,虚拟主机没有,也是加上就行了;
3、独立主机因为前面已经有了$1,所以后面就应该依次是$2,$3,改一下数字就行了。

今后大家再遇到这种情况就可以自己改了,呵呵。国外的cms一般都比较小家子气,首先界面和定位是博客,它以为它的用户也都全是只能买虚拟主机的,所以一般都不提供独立主机Rewrite规则。

呵呵,Sablog本来就是一个博客,所以不提供也正常啦,我还是把改好的规则拿出来和大家分享吧。


RewriteEngine On
RewriteRule ^(.*)/show-([0-9]+)-([0-9]+)\.html$ $1/index.php?action=show&id=$2&page=$3
RewriteRule ^(.*)/category-([0-9]+)-([0-9]+)\.html$ $1/index.php?action=index&cid=$2&page=$3
RewriteRule ^(.*)/archives-([0-9]+)-([0-9]+)\.html$ $1/index.php?action=index&setdate=$2&page=$3
RewriteRule ^(.*)/(archives|search|reg|login|index|links)\.html$ $1/index.php?action=$2
RewriteRule ^(.*)/(comments|tagslist|trackbacks|index)-([0-9]+)\.html$ $1/index.php?action=$2&page=$3

大家把这段加入之间就行了。
下面是改好的PHPBB 3.0 beta7 的独立主机规则,不分享浪费啊,呵呵。


RewriteEngine On
Rewriterule ^(.*)/(.+)-f([0-9]*).html-(.+)$ $1/viewforum.php?f=$3&$4
Rewriterule ^(.*)/(.+)-(t|p)([0-9]*).html-(.+)$ $1/viewtopic.php?$3=$4&$5
Rewriterule ^(.*)/(.+)-f([0-9]*)s([0-9]*).html-(.+)$ $1/viewforum.php?f=$3&start=$4&$5
Rewriterule ^(.*)/(.+)-(t|p)([0-9]*)s([0-9]*).html-(.+)$ $1/viewtopic.php?$3=$4&start=$5&$6
Rewriterule ^(.*)/(.+)-f([0-9]*).html$ $1/viewforum.php?f=$3&$4
Rewriterule ^(.*)/(.+)-(t|p)([0-9]*).html$ $1/viewtopic.php?$3=$4&$5
Rewriterule ^(.*)/(.+)-f([0-9]*)s([0-9]*).html$ $1/viewforum.php?f=$3&start=$4&$5
Rewriterule ^(.*)/(.+)-(t|p)([0-9]*)s([0-9]*).html$ $1/viewtopic.php?$3=$4&start=$5&$6

返回顶部