简体   繁体   中英

htaccess rewrite rule with query string, multiple variables and no php file in the link

We're trying to migrate our forum to another platform and we have encountered links which have queries in them, such as

http://forum.test/threads/119312-Warnight-CS-GO?p=2306618&viewfull=1#post2306618

which has to point to http://forum.test/threads/warnight-cs-go.119312/#post-2306618

So the logical structure of the original link is :

http://{forum_base_url}/threads/{thread-id}-{thread-permalink}?p={post-id}&viewfull={post-number-in-thread}#post{post-id}

While the new one is:

http://{forum_base_url}/threads/{thread-permalink}.{thread-id}/#post-{post-id}

So for the rewrite to work we need to "pull" three things out of the original link: the thread-id, the permalink, and the post-id. The first two aren't an issue, it's the third one which doesn't want to cooperate.

After scouring the Internet for possible solutions, we came up with:

RewriteCond %{QUERY_STRING} ^p=(\d+)&viewfull=(\d+)#post(\d+)$
RewriteRule ^threads/([0-9]+)-(.*)$ /threads/$2\.$1/#post-%1? [R=301,NC,L]

But unfortunately, the rewrite doesn't work.

What throws us off regarding the rewrite is that there are multiple variables in the query and no .php file specified in the link itself, so we can't just use the solution offered here: https://stackoverflow.com/a/2252242/1288397

Any tips on how to overcome this particular hurdle?

The #post- part of the URL is never sent to the server , it remains entirely on the browser's end, so there's no way to match against it. Luckily, the post ID is already in the query string so you can ignore it:

RewriteCond %{QUERY_STRING} ^p=(\d+)&viewfull=(\d+)$
RewriteRule ^threads/([0-9]+)-(.*)$ /threads/$2\.$1/#post-%1? [R=301,NC,L]

The other thing is that the thread-permalink is lowercase in your second URL. Not sure if that matters or not, but in order to change text to lowercase, you need to use a Rewrite Map , and the tolower internal function. You can only declare maps in the server vhost/config, so if you don't have access to those config files, you're not going to be able to use maps.

Thanks for clearing up the #post- aspect.

I tried your modification, but the links initially became:

http://forum.test/threads/warnight-cs-go.119312/%23post-2306618#post2306618

In order to work, the rewrite needs to be

RewriteCond %{QUERY_STRING} ^p=(\d+)&viewfull=(\d+)$
RewriteRule ^threads/([0-9]+)-(.*)$ /threads/$2\.$1/#post-%1? [R=301,NC,NE,L]

Notice the additional NE (noscape) flag at the end

That's because, by default, special characters, such as & and ?, will be converted to their hexcode equivalent. Using the [NE] flag prevents that from happening, as seen here: http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_ne

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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