【问题标题】:Mod Rewrite path issuesMod重写路径问题
【发布时间】:2010-12-17 20:52:00
【问题描述】:

我已成功创建重写规则来处理类似的 URL

http://example.com/xyz

http://example.com/xyz/

http://example.com/xyz/abc

http://example.com/xyz/abc/

这是模组重写和正则表达式:

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]

这很好用,但问题是当我转到 http://example.com/xyz/abc 时,我的脚本得到了正确的输入 (n=abc) 但路径搞砸了,所以我的代码中的所有相对 URL 都被破坏了,因为它们现在是相对于 xyz 而不是根。

有没有办法解决这个问题?正如您在上面看到的,我试图重定向到 /index.php 以强制路径正确。经过一整天的正则表达式和代码,我的大脑被炸毁了,所以我希望这不是一件极其微不足道的事情。

【问题讨论】:

    标签: php regex .htaccess mod-rewrite lamp


    【解决方案1】:

    使用 HTML base 元素强制所有相对 URL 使用与浏览器显示的路径不同的路径。

    <base href="http://www.example.com/"/>
    ...
    <a href="relative/url">link</a>
    

    相对 URL 将使用“http://www.example.com”作为其基础,即使浏览器认为它正在查看页面“http://www.example.com/xyz/”。所以链接转到“http://www.example.com/relative/url”而不是“http://www.example.com/xyz/relative/url

    还有 Stack Overflow 的做法,其中每个 URL 要么是绝对路径(指向图像等资源),要么是包含根的路径(即“/feeds/questions/123”),从而避免了相对路径问题。

    【讨论】:

    • 请注意,更改基本 URI 将影响 每个 相对 URI,而不仅仅是以 URI 路径开头的那些。
    【解决方案2】:

    三个选项是:

    1) 使用基本标签(这将影响页面上的每个相关 URI,包括链接、图像、脚本、样式表等)

    <base href="http://yoursite/">
    

    2) 将所有链接更改为完全限定的 URI

    <a href="http://yoursite/yourpage.html">
    

    3) 使用“/”前缀表示路径是相对于每个 URI 上的根的。

    <a href="/yourpage.html">
    

    我个人最常使用 base-tag 选项,这确实得到了一些不好的报道(来自那些在没有真正理解的情况下使用它的人)。对于 mod_rewrite,基本标签是完美的,因为您可能确实希望所有路径都相对于根,包括所有图像、css、脚本和链接。

    【讨论】:

    • 你和 Welbog 都有很好的答案。把被接受的给你作为失败者的点数。谢谢。
    【解决方案3】:

    编辑:我假设您在 HTML 代码中谈论 URL,例如到损坏的图像和样式表。

    不,据我所知,没有办法绕过它,因为浏览器会看到一条路径,并请求相对于它的资源。它与服务器无关,您也无能为力。

    您将不得不求助于不被解释为目录拆分器的不同拆分器(例如下划线),或者使用绝对路径,或者使用<base> tag。然而,我自己从未使用过基本标签,而且无论你在哪里看,它都不是很好。最好的办法可能是切换到绝对路径。

    【讨论】:

    • 感谢您的意见...我有点希望有办法解决它。请让我知道您是否阅读过明确指出这种情况的信息,我会接受这个答案。
    • 请注意,更改基本 URI 将影响 每个 相对 URI,而不仅仅是以 URI 路径开头的那些。
    • @Antony:我敢肯定,如果您继续使用斜杠,您将无法绕过它——路径就是路径。您是否考虑过为您的虚拟路径使用不同的字符?这看起来不太好,但确实有效。我见过使用逗号,在我看来这还不错,尽管它并不完全合法。
    • @pekka 不幸的是,由于项目要求,我需要使用这个 URL 结构,但我同意不同的分隔符会更合适。
    • @Pekka Gaiser:使用其他字符代替段分隔符/ 对于 URL 具有完全不同的含义,因为段通常表示层次结构。
    【解决方案4】:

    修改您的最后一个 RewriteRule 以包含路径。你在正则表达式中有路径。

    RewriteRule ^/?([-a-zA-Z0-9_+]+)/([-a-zA-Z0-9_+]+)(?:\/)?$ $1/index.php?n=$2 [L]
    

    或者(取决于你想要达到的目标):

    RewriteRule ^/?([-a-zA-Z0-9_+]+)/([-a-zA-Z0-9_+]+)(?:\/)?$ /index.php?n=$1/$2 [L]
    

    【讨论】:

    • 这与我想要的相反 - 它需要使用根目录。
    【解决方案5】:

    我尝试在我的页面中使用 BASE 元素作为快捷方式,而不是更改所有 url。添加基本​​元素如下:

    <base href="/">
    

    结果如下:

    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">
    

    您始终可以在必要时覆盖基本标记:

    This:    <a href="/foo">
    Remains: <a href="/foo">
    
    This:    <a href="/foo/bar/">
    Remains: <a href="/foo/bar/">
    

    【讨论】:

    • 请注意,更改基本 URI 将影响 每个 相对 URI,而不仅仅是以 URI 路径开头的那些。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多