How do I preserve uri fragment in safari upon redi

2019-01-22 21:59发布

问题:

My gwt / gae application utilizes activities and places. In order to create asynchronous processes (such as resetting a password or verifying ownership of an email address) I use a pattern where an activity's state can be tokenized and stored in the datastore, then retrieved and resumed later. In order to retrieve the state token I have a place which takes an augmented token id as an argument, fetches it from the datastore, then navigates to the appropriate place as necessary to resume to process. This enables me to create a link to a specific state of my application which can be distributed via email. for example:

http://mydomain.com/#signup:anJlbmZyb0BldGhvc2VkZ2UuY29tfDEzNzQxOTIxNjU3NjQ=

In this case, the above link would be sent to the email addres used during signup and the application will resume the signup activity identified by the hash argument.

Everything has been working well until recently when I added an SSL cert and enforced https for all requests by adding the following code to my web.xml:

<security-constraint>
    <web-resource-collection>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

This constraint enforces https via (I believe) a 301 redirect to port 443. Works like a charm in Chrome, Firefox and IE.... however safari seems to drop the url fragment upon redirect... I think you can see my problem! How do I prevent safari from dropping the url fragment?!

Update 8.1.13

After exhausting research, I think I have identified the root cause, but I have yet to find a good solution. A thorough description of the problem was provided in the w3c memo Handling of fragment identifiers in redirected URLs (1999)

Basically, http spec was unclear as to the handling of url fragments during 3xx redirects; and safari chose to drop the fragment when redirected. See the following bugzilla bug:

https://bugs.webkit.org/show_bug.cgi?id=24175

The desired behavior is described by w3c's commun user agent problems:

http://www.w3.org/TR/cuap#uri

So in light of all this, I believe that this is a safari (webkit) issue. What I don't understand is why aren't other webkit browsers affected? Is there a known workaround?

回答1:

Just serve a redirect page (200) that refreshes the window.location upon load and injects the hash fragment.

<!DOCTYPE html>
<meta charset="utf-8">
<html>
<body>
<script>
    var hash = (location.href.split("#")[1] || null);
    var pathField = "{{redirectUri}}";
    if (hash) {
        if (pathField.indexOf("#") == -1) {
            pathField = pathField + "#" + hash;
        }
    }
    window.location = pathField;
</script>
</body>
</html>

That way, it works with every browser (at least browsers that support javascript). {{redirectUri}} is the URL you want to redirect to. If it contains a fragment already, it won't be overwritten.