wordpressapache.htaccesshttptrailing-slash

Can't remove trailing slash from WordPress base URL in subdirectory


I have a WordPress in the directory www.example.com/blog/ and it works fine. All the URLs ended in '/' (www.example.com/blog/article/), but I have corrected it from Settings/Permalinks (www.example.com/blog/article). There is only one URL that I can't manage to remove the final '/', www.example.com/blog/, I need it to be www.example.com/blog.

When I save in Settings/Permalinks WordPress modifies the .htaccess to:

# BEGIN All In One WP Security
#AIOWPS_BLOCK_SPAMBOTS_START
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} ^(.*)?wp-comments-post\.php(.*)$
RewriteCond %{HTTP_REFERER} !^http(s)?://(.*)?\.example\.com/blog [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule .* http://127.0.0.1 [L]
</IfModule>
#AIOWPS_BLOCK_SPAMBOTS_END
# END All In One WP Security

# BEGIN WordPress
# Las directivas (líneas) entre «BEGIN WordPress» y «END WordPress» son
# generadas dinámicamente y solo deberían ser modificadas mediante filtros de WordPress.
# Cualquier cambio en las directivas que hay entre esos marcadores serán sobrescritas.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>

# END WordPress

I've changed RewriteBase /blog/ to RewriteBase /blog, but it's not the solution. I don't understand why WordPress generates the RewriteBase with /blog/ directly and not with /blog, because the site and WordPress address in Settings/General is www.example.com/blog.

Inspecting from Google Chrome I see that there is a 301 redirect from www.example.com/blog to www.example.com/blog/, but I think it is done by WordPress itself.


Solution

  • This is an ancient (in web years) conundrum.

    If https://example.com/foo/index.html is the URL of an actual file on your Apache or nginx server, that means that https://example.com/foo, oddly enough, is not and cannot be a valid URL. URLs map to file names, and foo isn't a file name. It is a directory name. But Apache and nginx don't deliver directory contents. On the other hand, the web server sees https://example.com/foo/, a missing file name, and substitutes the default filename (index.php in the WordPress world).

    But it would drive people crazy to get a 404 every time we forgot the trailing /. So, the web server handles this by responding with a 301 (permanent redirect) response redirecting the browser to https://example.com/foo/ including the trailing /. At the end of the pageload you'll see that trailing / in your browser location bar.

    You can see this unfold in your browser devtools Network tab if you try it.

    So, I believe you're trying to do something that can't easily be done in the WordPress over Apache or nginx webserver world.

    Other, more recently developed, web server software (node express, etc) has more flexible request routing (URL pathname interpretation) facilities. But Apache's origins are in the days when a web server simply mapped a local filesystem to URLs.