Search code examples
angularapache.htaccesshttp-redirecturlencode

Htaccess redirect to index.html including semicolons and urlencoded characters


I have an Angular application, so I want all traffic to be redirected to index.html so that Angular can take care of it.

Currently, I have the following htaccess:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^.*$ /index.html [L,NC,QSA,NE]
</IfModule>

When I refresh a page, everything correctly refreshes, but some important pages use Angular's ActivatedRoute.paramMap to pass state around, and URLs come to look like this: https://example.com/thing/edit;id=16;language=en;data=n%2Fa If I refresh on those pages, I get a 404 error.
Note that normal navigation to those pages (e.g. by clicking links) works fine.
If I manually type a URL with correct parameters and data, I get a 404. However, the errors only seem to happen while there are encoded characters in the URL, such as the above %2F. If no encoded sequence is the URL, the behaviour is correct.

The desired output is that, when I refresh on a page with those kinds of URLs including URL-encoded characters, I don't get a 404, but the correct page, including all the parameters with semicolons for Angular to parse.

I know close to nothing about Apache and htaccess, and what tips I could find for similar problems on SO and google didn't help.


Solution

  • such as the above %2F

    %2F (encoded slash) and %5C (encoded backslash) are special cases and by default Apache will throw a 404 if these encoded characters appear in the URL-path portion of the URL.

    This is a "security" feature, since "allowing slashes to be decoded could potentially allow unsafe paths." (source)

    To allow encoded slashes in the URL, but not decode them server-side, but allow the URL to be passed through, you can set the following in the server config or directly in the <VirtualHost> container (and restart Apache):

    AllowEncodedSlashes NoDecode
    

    The NoDecode option requires Apache 2.4. (On Apache 2.2 you would need to use On - but this also decodes slashes before being passed to the backend.)

    Note that the AllowEncodedSlashes directive cannot be used in a .htaccess (or <Directory>) context.

    Reference: