MoOx / pjax

Easily enable fast Ajax navigation on any website (using pushState + xhr)
MIT License
1.43k stars 124 forks source link

Could not handle 301/302 redirect probably. #216

Open KawaiiZapic opened 4 years ago

KawaiiZapic commented 4 years ago

When a target of a link try to make a 301/302 redirect to other site that not in this domain,PJAX will also try to request it and blocked by the browser for security reason.
And user will not get a probably redirect.

For an example: On http://www.example.com/index.html ,there is a link to http://www.example.com/login.html .
But the login.html made a 301 redirect to http://login.example.net/login.php ,and this script could not redirect to login.php probably.

iangreenleaf commented 3 years ago

I just ran into this recently. It's a tough one because browsers handle redirects transparently in XmlHttpRequest, so the PJAX JS can't stop the request from going to the external URL (and probably erroring on a CORS failure). To fix this without server modifications, I think this script would need to migrate to the fetch API, which has more control over redirect behavior.

Because I do have control over my server, I was able to work around it as follows:

  1. On the server, when redirecting I check for the x-pjax header. If it's present, instead of returning a 301/302 I return a 204 with a x-pjax-location header set (the name of this header can be anything, I'm the only one using it).
  2. On the client, I added this:

      pjax._handleResponse = pjax.handleResponse;
    
      pjax.handleResponse = function(responseText, request, href, options) {
        var redirect = request.getResponseHeader("x-pjax-location")
        if (redirect) {
          window.location = redirect
        } else {
          pjax._handleResponse(responseText, request, href, options);
        }
      }