Amazon S3 Redirect Rule - Preserve Query Params

13,590

Solution 1

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.

Solution 2

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 :)

Solution 3

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.
Share:
13,590

Related videos on Youtube

Andrew Rasmussen
Author by

Andrew Rasmussen

Founder of Canny. Used to work on ReactJS at Facebook.

Updated on June 07, 2022

Comments

  • Andrew Rasmussen
    Andrew Rasmussen almost 2 years

    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?

    • Michael - sqlbot
      Michael - sqlbot almost 9 years
      Out of curiosity, does /foo/?ping=pong work as expected? (adding a trailing slash before the ?)
    • doublejosh
      doublejosh over 6 years
  • Nikhila Ravi
    Nikhila Ravi almost 8 years
    Thanks for the tip - I tried setting this up in cloudfront but when I look at the sources tab in Chrome inspector, is is loading the index.html page as my bundle.js file and so I'm getting an unexpected token < error. My website urls are of the from https://mydomain.io/search/0.1/index.html/article/uuid. And in react router I have a basename of search/0.1/index.html' so one of the route definitions is for article/:id. S3 still seems to be looking for the folder /search/0.1/index.html/article. Any ideas how I can solve this issue?
  • James Parker
    James Parker almost 7 years
    Yes!! Lifesaver!
  • Andrew Rasmussen
    Andrew Rasmussen over 6 years
    @doublejosh: You mean just hitting up S3 directly? Query params shouldn't be ignored then. In my case, CloudFront was removing query params, that was my problem. If you aren't using CloudFront, you shouldn't be experiencing the same issue.
  • doublejosh
    doublejosh over 6 years
    Query params seem to be stripped with just S3 folder redirects, eg: /my-page?this=that >>> /my-page/
  • zylo
    zylo about 4 years
    Any luck @doublejosh? Having the same issue.
  • doublejosh
    doublejosh about 4 years
    Not able to find a solution to that other than being super careful are always sharing URLs with a final slash before the question mark.
  • jwadsack
    jwadsack almost 3 years
    For anyone looking for details on this, it's currently CloudFront Distributions > [click distribution] > Behaviors > [check behavior] > Edit > Cache Policy -> Create New Policy > Query strings > [select All]. Save. Save. Save.