简体   繁体   English

如何在 URL using.htaccess 中用破折号替换下划线?

[英]How to replace underscores with dashes in URL using htaccess?

I have URL that looks like this example.com/test-page/now_here , but I want the URL to look like example.com/test-page/now-here .我有 URL 看起来像这个example.com/test-page/now_here ,但我希望 URL 看起来像example.com/test-page/now-here

I have tried the following in my .htaccess file:我在我的.htaccess文件中尝试了以下内容:

RewriteRule       ^(/?test-page/.*/[^/]*?)_([^/]*?_[^/]*)$ $1-$2 [N]
RewriteRule       ^(/?test-page/.*/[^/]*?)_([^/_]*)$       $1-$2 [R=301]

But it did not work.但它没有用。 I get a 404 error when I goto /test-page/now-here当我转到/test-page/now-here时出现 404 错误

What am I doing wrong?我究竟做错了什么?

Here is my full .htaccess :这是我的完整.htaccess

Options -Indexes

<IfModule mod_rewrite.c>
    Options +FollowSymLinks
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php/$1 [L]
    RewriteCond %{HTTPS} !=on
    RewriteCond %{HTTP_USER_AGENT} ^(.+)$
    RewriteCond %{SERVER_NAME} ^example\.com$
    RewriteRule .* https://www.%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
    RewriteRule       ^(/?test-page/.*/[^/]*?)_([^/]*?_[^/]*)$ $1-$2 [N]
    RewriteRule       ^(/?test-page/.*/[^/]*?)_([^/_]*)$       $1-$2 [R=301]
    Header add Strict-Transport-Security "max-age=300"
</IfModule>
<IfModule mod_headers.c>
    <If "%{REQUEST_SCHEME} == 'https' || %{HTTP:X-Forwarded-Proto} == 'https'">
        Header always set Strict-Transport-Security "max-age=31536000"
    </If>
</IfModule>

UPDATE更新

@MrWhite solution did work, and now when I goto the url test-page/now_here it goes to test-page/now-here, however its not going to my php method in my test page controller, here is the full code: @MrWhite 解决方案确实有效,现在当我转到 url test-page/now_here 时,它会转到 test-page/now-here,但是它不会转到我的测试页 controller 中的 php 方法,这是完整代码:

class TestPage_Controller extends App_Controller {
    function index() {
        $this->smarty->assign('currentPage', 'testpage');
        $this->smarty->assign('pageTitle', 'Test Page');
        $this->smarty->assign('description', "This is a test page.");
        $this->smarty->display(MDCHAT_THEME . '/page_meta.tpl');
        $this->smarty->display(MDCHAT_THEME . '/page_header.tpl');
        $this->smarty->display(MDCHAT_THEME . '/test_page.tpl');
        $this->smarty->display(MDCHAT_THEME . '/page_footer.tpl');
    }

    function now_here() {
        $this->smarty->assign('currentPage', 'testpage');
        $this->smarty->assign('pageTitle', 'Test Page');
        $this->smarty->assign('description', "This is a test page.");
        $this->smarty->display(MDCHAT_THEME . '/page_meta.tpl');
        $this->smarty->display(MDCHAT_THEME . '/page_header.tpl');
        $this->smarty->display(MDCHAT_THEME . '/here.tpl');
        $this->smarty->display(MDCHAT_THEME . '/page_footer.tpl');
    }
}

All I get when I goto test-page/now-here I get a blank white page even after I turned on php errors via php.ini display_errors = on and in my php code:当我转到测试页面/现在-这里时,我得到的只是一个空白页面,即使我通过 php.ini display_errors = on和我的 php 代码打开了 php 错误:

error_reporting(E_ALL);
ini_set('display_errors', 1);

Still just a white screen.仍然只是一个白屏。

 RewriteEngine On RewriteCond %{REQUEST_FILENAME}.-f RewriteCond %{REQUEST_FILENAME}.-d RewriteRule ^(.*)$ index.php/$1 [L] RewriteCond %{HTTPS}.=on RewriteCond %{HTTP_USER_AGENT} ^(:+)$ RewriteCond %{SERVER_NAME} ^example\.com$ RewriteRule,* https?//www.%{SERVER_NAME}%{REQUEST_URI} [R=301?L] RewriteRule ^(/?test-page/?*/[^/]*.)_([^/]*?_[^/]*)$ $1-$2 [N] RewriteRule ^(/?test-page/.*/[^/]*?)_([^/_]*)$ $1-$2 [R=301]

Your rules are in the wrong order, so the directives won't actually be processed for the given URL. But the regex in that rule doesn't match the example URL either, so wouldn't do anything anyway.您的规则顺序错误,因此实际上不会为给定的 URL 处理指令。但是该规则中的正则表达式也不匹配示例 URL,因此无论如何都不会执行任何操作。

The regex you are using would match /test-page/something/now_here , not /test-page/now_here as in your example.您使用的正则表达式将匹配/test-page/something/now_here ,而不是您示例中的/test-page/now_here The .*/ after test-page/ is extra based on your example. test-page/之后的.*/根据您的示例是额外的。

Your existing (what looks-like) HTTP to HTTPS and non-www to www canonical redirect is also in the wrong place (it needs to go before the rewrite to the front-controller, otherwise it will end up redirecting to index.php ), but it would also fail to canonicalise http://www.example.com/ (HTTP + www) and https://example.com/ (HTTPS + non-www).您现有的(看起来像)HTTP 到 HTTPS 和非 www 到 www 规范重定向也位于错误的位置(在重写到前端控制器之前需要 go,否则它将最终重定向到index.php ) ,但它也无法规范化http://www.example.com/ (HTTP + www)https://example.com/ (HTTPS + 非 www)。 As written, it only canonicalises http://example.com/ (HTTP + non-www).如所写,它仅规范化http://example.com/ (HTTP + 非 www)。

Try the following instead:请尝试以下操作:

RewriteEngine On

# 1.0 - Replace underscores with hyphens in last path segment
RewriteRule ^(test-page/[^/]*?)_([^/]*?_[^/]*)$ $1-$2 [N]

# 1.1 - Redirect to remove the final underscore
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+?)\.?$ [NC]    
RewriteRule ^(test-page/[^/]*?)_([^/_]*)$ https://www.%1/$1-$2 [R=301,L]

# 2 - non-www to www AND HTTP to HTTPS
RewriteCond %{HTTP_USER_AGENT} .
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+?)\.?$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L]

# 3 - Rewrite to front-controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php/$1 [L]

NB: Test with a 302 (temporary) redirect first to avoid potential caching issues.注意:首先使用 302(临时)重定向进行测试以避免潜在的缓存问题。

I would also question why you are only redirecting (canonicalising) requests from user-agents that pass a +ve User-Agent string.我还会质疑为什么您只重定向(规范化)来自传递 +ve User-Agent字符串的用户代理的请求。 (Yes, it's quite possibly a malicious bot.) Yet you are still passing such requests to your front-controller and not blocking it. (是的,它很可能是一个恶意机器人。)然而你仍然将这样的请求传递给你的前端控制器而不是阻止它。 (?) I've left this condition in the above rule, just simplified it, in case you have some specific requirements. (?) 我在上面的规则中留下了这个条件,只是简化了它,以防你有一些特定的要求。

You probably do not want the <IfModule mod_rewrite.c> wrapper.您可能不想要<IfModule mod_rewrite.c>包装器。 With this <IfModule> directive in place and mod_rewrite was suddenly not available then your site will no doubt break in a non-obvious way and you'll likely get a ton of 404s, which may not be picked up for a while.有了这个<IfModule>指令并且 mod_rewrite 突然不可用,那么你的网站无疑会以一种不明显的方式中断,你可能会得到大量的 404,这可能有一段时间不会被拾取。 Without this <IfModule> directive then the site will break with a detailed error in the server's error log which should potentially trigger an alert/notification.如果没有此<IfModule>指令,则站点将因服务器错误日志中的详细错误而中断,这可能会触发警报/通知。 See the following question on Webmasters SE for more info on this: https://webmasters.stackexchange.com/questions/112600/is-checking-for-mod-write-really-necessary有关更多信息,请参阅网站管理员 SE 上的以下问题: https://webmasters.stackexchange.com/questions/112600/is-checking-for-mod-write-really-necessary

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM