6

I try to redirect all urls to the root except for the wordpress administration and the wordpress REST API.

I have these rules in my .htaccess:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/wp-admin.*
RewriteCond %{REQUEST_URI} !^/wp-json.*
RewriteRule ^.*$ / [L,R=301]
</IfModule>

It's work perfectly for all redirections expect for the /wp-json route where I get 404 errors.

Also, I have these errors types in my apache log file: File does not exist: [...]/dmjob/wp-json, referer: http://dmjob.dev:8888/

Can you please help me ? Thanks a lot ! :)

Quentin Brosse
  • 63
  • 1
  • 1
  • 4
  • Questions like this might be better suited to the [WordPress Stack](https://wordpress.stackexchange.com/). (Although you're more likely to get a WP specific solution, rather than an Apache config solution.) – MrWhite May 31 '17 at 10:56

2 Answers2

5

You seem to have destroyed the WordPress front-controller, so any requests for the /wp-admin and /wp-json will not be correctly routed (hence the 404s you are seeing).

You should leave the WP directives as they were, but implement an additional redirect at the start of the file. For example:

# Redirect all requests for non-existent files and those not for wp-admin or wp-json
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/wp-admin
RewriteCond %{REQUEST_URI} !^/wp-json
RewriteRule ^ / [R=301,L]

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Note that, as in your original code, the request is only redirected when requesting a non-existent file, even if that file lies outside of the /wp-admin and /wp-json URL space. (Presumably this is required so that CSS, JS, images and any other static resources still get served correctly.)

MrWhite
  • 12,647
  • 4
  • 29
  • 41
0

Let's see what your rules are doing.

  1. You enable the rewriting engine set the base URL for per-directory rewrites. That's ok.

    RewriteEngine On
    RewriteBase /
    
  2. Then, you state that no subtitution - should be done for /index.php. That's ok, too.

    RewriteRule ^index\.php$ - [L]
    
  3. The rest of the conditions causes the rule in the last line to be applied.

    The redirection to / is done whenever the file or directory doesn't exist or the request URL isn't /wp-admin.* or /wp-json.*:

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !^/wp-admin.*
    RewriteCond %{REQUEST_URI} !^/wp-json.*
    RewriteRule ^.*$ / [L,R=301]
    

There's nothing wrong with any of these. The url http://example.com/wp-json/ and anything beneath doesn't meet the last condition ant the RewriteRule is not applied.

The 404 Not Found error is an indication you don't have the /wp-json at all. The (human readable) error in your logs suggests the same. If you didn't have the last rule, the first two rules of non-existing files would have been met, causing the redirection to the /. Having the last rule prevents this redirection, causing 404.

Esa Jokinen
  • 46,944
  • 3
  • 83
  • 129