Get final URL from XHR object after redirect

Suppose I use ajax (e.g. via jQuery) to execute a POST request in an API that implements a PRG pattern. Therefore, this will redirect me to:

POST /some/api HTTP/1.1 303 See Other Location: /some/other/location 

Then jQuery will automatically redirect and do:

 GET /some/other/location 

And then call the response handlers (success, failure, etc.) with the result of the last request. However, how can I read the location of the final resource ( /some/other/location in this case) in javascript?

+8
jquery redirect ajax
source share
5 answers

As far as I know, this is not possible with the XMLHttpRequest object. But if you work in the [trusted] domain, and if this is important information, you can use iframe instead:

 var hidden_iframe = document.createElement('iframe'); hidden_iframe.name = 'hidden_iframe'; hidden_iframe.style.display = 'none'; hidden_iframe.onload = function() { console.log(hidden_iframe.contentWindow.location.toString()); } document.body.appendChild(hidden_iframe); var request = document.createElement('form'); request.method = 'post'; request.action = '/some/api'; request.target = 'hidden_iframe'; request.style.display = 'none'; // append INPUTs to the request form here document.body.appendChild(request); request.submit(); 

Your console should report 1 or more URLs, the last of which will be:

http(s)://{yourdomain}/some/other/location

+5
source share

XMLHttpRequest does not provide a final URL.

: [

But , you can hack this without using an iframe. If you return a JSON object, you can add a finalURL property, for example the following:

 { "finalURL": "http://example.com/API/v2/request.json", "response": {...} } 

and read this to get the url after the redirect. Hope this is helpful!

+4
source share

I believe this is not possible at all, although I see through Chrome Developer Tools that the browser receives 303 responses from the server and then follows the redirect.

See this sibling question and answer: Is it possible for XHR HEAD requests to not match forwarding (301 302)

0
source share

This is an old post, but it is highly regarded by Google, so I will add my solution.

If you have control over the ajax response, you can add a header to the response with the final URL.

In PHP, it will be something like:

header('X-final-url: /some/other/location') .

Then in jquery you can access this value with:

var finalUrl = jqXHR.getResponseHeader('X-final-url');

I am adding a header to Symfony using a kernel listener:

Service

 app.kernel.response_metadata_populator: class: AppBundle\Listeners\ResponseMetadataPopulator tags: - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse } 

Listener class

 class ResponseMetadataPopulator { /** * @param FilterResponseEvent $event */ public function onKernelResponse(FilterResponseEvent $event) { $response = $event->getResponse(); $response->headers->set('X-FINAL-URL', $event->getRequest()->getRequestUri()); } } 
0
source share

Although this is an old post, hope this updated (2018) answer helps someone. Please note that this solution does not work in Internet Explorer (any version) and only works in relatively modern versions of other browsers.

XMLHttpRequest now provides a read-only responseURL property that returns the responseURL URL after any redirects .

 var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://example.com', true); xhr.onload = function () { console.log(xhr.responseURL); // Prints http://example.com }; xhr.send(); 

See Docs at https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseURL.

0
source share

All Articles