Before I used redirect 301 statement.
Now I'm in a position where I need to use the RewriteRule statement to make use of the flags (redirecting without the query string),
but for some reason, it's not working.
This is my .htaccess file:
# BEGIN WordPress
# Директивы (строки) между `BEGIN WordPress` и `END WordPress`
# созданы автоматически и подлежат изменению только через фильтры WordPress.
# Сделанные вручную изменения между этими маркерами будут перезаписаны.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
#this is working
redirect 301 /bad-link/ http://localhost:8000/
#this is not working
RewriteRule ^test/bad-link.*$ "http://localhost:8000" [NC,QSD,L,R=301]
#this is also not working
RewriteRule "test/bad-link" "http://localhost:8000" [R=301]
</IfModule>
# END WordPress
You have the directives in the wrong order. The mod_rewrite redirects (ie. RewriteRule directives) need to go before the WordPress front-controller rewrites. By placing them after the WordPress directives they are never going to be processed since the request has already been rewritten to the WP front-controller (index.php) and processing stops.
You should not edit the code inside the # BEGIN WordPress / # END WordPress code block as WordPress itself tries to maintain this code block and your edits can get overwritten.
You should place your RewriteRule 301 redirect directives before the # BEGIN WordPress comment marker. You do not need to repeat the RewriteEngine On directive that occurs later, inside the WordPress code block.
The mod_alias Redirect directive would have "worked" because it is not dependent on the ordering of directives in relation to the other mod_rewrite directives. Different Apache modules run independently and at different times during the request, regardless of the order of the directives in the config file. mod_rewrite runs before mod_alias and the Redirect always runs regardless of the outcome of the preceding mod_rewrite directives (unless they trigger an external redirect).
In other words:
# External redirects...
RewriteRule ^test/bad-link http://localhost:8000/ [NC,QSD,R=301,L]
# BEGIN WordPress
: etc.
Note that the .*$ at the end of your regex is superfluous.
NB: Test first with 302 (temporary) redirects to avoid potential caching issues.