可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have successfully created rewrite rules to handle URLs like
http://example.com/xyz
http://example.com/xyz/
http://example.com/xyz/abc
http://example.com/xyz/abc/
Here is the mod rewrite & regex:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([0-9]+)(?:\/)?$ /index.php?p=$1 [L]
RewriteRule ^/?([-a-zA-Z0-9_+]+)(?:\/)?$ /index.php?n=$1 [L]
RewriteRule ^/?([-a-zA-Z0-9_+]+)/([-a-zA-Z0-9_+]+)(?:\/)?$ /index.php?n=$2 [L]
This works great, but the problem is that when I go to http://example.com/xyz/abc, my script gets the correct input (n=abc) but the paths are messed up, so all relative URLs in my code are broken, as they are now relative to xyz instead of the root.
Is there a way around this at all? As you can see above I have tried to redirect to /index.php to force the path to be correct. My brain is fried after a long day of regex and code, so I hope it's not something disastrously trivial.
回答1:
The three options are:
1) Use a base tag (this will affect every relative URI on your page, including links, images, scripts, stylesheets and so on)
<base href="http://yoursite/">
2) Change all of your links to fully qualified URIs
<a href="http://yoursite/yourpage.html">
3) Use the "/" prefix to show that the path is relative to the root on each URI.
<a href="/yourpage.html">
I have personally used the base-tag option the most, which does get some bad press (from people that have used it without really understanding it). When it comes to mod_rewrite, the base tag is perfect as you probably DO want all your paths to be relative to the root, including all your images, css, scripts and links.
回答2:
Use the HTML base
element to force all relative URLs to use a different path than the one the browser displays.
<base href="http://www.example.com/"/>
...
<a href="relative/url">link</a>
The relative URL will use "http://www.example.com" as its base, even if the browser thinks it's looking at the page "http://www.example.com/xyz/". So the link goes to "http://www.example.com/relative/url" instead of "http://www.example.com/xyz/relative/url"
And there's the Stack Overflow way of doing it, in which every URL is either an absolute path (to resources like images) or paths including the root (i.e. "/feeds/questions/123"), which avoid the relative path issues.
回答3:
Edit: I assume you are talking about URLs in your HTML code, e.g. to images and stylesheets, that are broken.
Nope, as far as I know there is no way around it, because the browser sees a path, and requests resources relative to it. It has nothing to do with the server, and there is nothing you can do.
You will either have to resort to a different splitter that is not interpreted as a directory splitter (e.g. underscores), or use absolute paths, or use the <base> tag. I have never used the base tag myself, however, and it is not very well regarded wherever you look. The best thing would probably be to switch to absolute paths.
回答4:
modify your last RewriteRule to include the path. you have the path in the regular expression.
RewriteRule ^/?([-a-zA-Z0-9_+]+)/([-a-zA-Z0-9_+]+)(?:\/)?$ $1/index.php?n=$2 [L]
or alternatively (depending on what you are trying to achieve):
RewriteRule ^/?([-a-zA-Z0-9_+]+)/([-a-zA-Z0-9_+]+)(?:\/)?$ /index.php?n=$1/$2 [L]
回答5:
I tried using the BASE element in my pages as a shortcut instead of changing all urls. Add the base element as follows:
<base href="/">
And here are the results:
This: <link type="text/css" rel="stylesheet" href="my.css">
Becomes: <link type="text/css" rel="stylesheet" href="/my.css">
This: <script type="text/javascript" language="javascript" src="include/my.js"></script>
Becomes: <script type="text/javascript" language="javascript" src="/include/my.js"></script>
This: <a href="foo.html">
Becomes: <a href="/foo.html">
This: <a href="foo/bar.html">
Becomes: <a href="/foo/bar.html">
You can always override the base tag where necessary:
This: <a href="/foo">
Remains: <a href="/foo">
This: <a href="/foo/bar/">
Remains: <a href="/foo/bar/">