Amazon S3 Redirect Rule - Preserve Query Params

18.3k views Asked by At

I noticed Amazon S3 Redirect rule - GET data is missing but after following the accepted answer my query params still are not being preserved.

I have a site that uses React and React Router, meaning I have several URLs that load identical HTML and JS and then the JS figures out which part of the app to load based on the URL.

For example:

/foo, /bar, /baz all should load index.html, which loads bundle.js. Then bundle.js observes the URL and routes to some React component (also in bundle.js).

However no foo, bar, or baz file exists in S3, only index.html. What I want to do is when I get a 404, redirect to /#!/{URL} (eg. /foo redirects to /#!/foo). This works fine with my redirect rule (below). However, I also want to bring query params with me (eg. /foo?ping=pong redirects to /#!/foo?ping=pong) but instead /foo?ping=pong just redirects to /#!/foo.

Here are my redirect rules:

<RoutingRules>
    <RoutingRule>
        <Condition>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <Protocol>http</Protocol>
            <HostName>www.mydomain.com</HostName>
            <ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
</RoutingRules>

Any ideas on some way I can achieve this? Ideally without having to go change something in S3/CloudFront every time I add a new page?

3

There are 3 answers

7
Andrew Rasmussen On BEST ANSWER

The problem was that I had the origin set up in CloudFront not to forward Query Strings so when S3 got the request it would redirect properly without the query params. You can find this setting in CloudFront > Behaviors > Forward Query Strings.

1
Aidin On

The menus and options in CloudFront/S3 change a lot over time.

Here is a December 2021 solution.

Step 1) Create a "Request" Policy in CloudFront that allows QueryStrings

enter image description here

Note: you might want to also add some Headers like Origin or Access-Control-... headers for CORS.

Step 2) Go to your Distribution > Update the Origin request policy

enter image description here

Step 3) Kick a new Invalidation on /*

enter image description here


Additional Notes for Debuging/Testing

  1. I would recommend testing with curl in terminal rather than a browser to avoid caching and also seeing the details. I do curl -v https://example.com/cb?foo=bar1.
  2. Keep increasing the value of the query string (bar1 in the above example, to bar2, bar3) with every test to make such there is no caching again.
1
Adrian Serafin On

If you want to have clear urls though you can also check out this trick. You need to setup cloudfront distribution and then alter 404 behaviour in "Error Pages" section of your distribution. That way you can again domain.com/foo/bar links :)