Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AJAX redirect dilemma, how to get redirect URL OR how to set properties for redirect request

First, I'm working in Google Chrome, if that helps. Here is the behavior:

I send an xhr request via jQuery to a remote site (this is a chrome Extension, and I've set all of the cross-site settings...):

$.ajax({
    type: "POST",
    contentType : "text/xml",
    url: some_url,
    data: some_xml,
    username: user,
    password: pass,
    success: function(data,status,xhr){
        alert(data);
    },
    error: function(xhr, status, error){
        alert(xhr.status);
    }
});

The URL that is being set returns a 302 (this is expected), and Chrome follows the redirect (also expected).

The new URL returns a prompt for credentials, which are not being pulled from the original request, so Chrome shows a login dialog. If I put in the original credentials, I get back a response about invalid request sent (it's a valid HTTP request -- 200 -- the remote server just doesn't like one of the headers).

When viewing the developer window in Chrome, there are two requests sent. The first is to the original URL with all settings set in the AJAX request. The second is to the redirect URL, with a method of "GET", nothing from the "POST" field, and no credentials.

I am at a loss as to what I can do. I either need to:

  1. Get the redirect URL so I can send a second request (xhr.getResponseHeader("Location") does NOT work),

  2. Have the new redirect request preserve the settings from the original request, or

  3. Get the final URL that the error came from so I can send another request.

Ideally I don't want the user to have to put in their credentials a second time in this dialog box, but I'll take what I can get if I can just get the final URL.

like image 843
Anthony Avatar asked May 10 '10 07:05

Anthony


1 Answers

Based on your question, I am not entirely sure if you are referring to HTTP Authentication or a form-based authentication scheme, and therefore I will address both.

Get the redirect URL so I can send a second request (xhr.getResponseHeader("Location") does NOT work),

With the way XHR is built in general (and in Chrome specifically): XHR is not very flexible, and provides a relatively high-level API, with the same behavior the browser has in all other requests (address bar urls, image source urls, embedded script urls), i.e. redirects are handled transparently. No events will be thrown in the JavaScript alerting you of this redirect or the intermediate 302/301 status codes, you will only receive the final status code and data. Therefore, it is impossible to retrieve the "Location" header from the response, as the final response will not contain the "Location" header.

Have the new redirect request preserver the settings from the original request,

XHR does not provide this as an option and it would be an incorrect default behavior. Example for why this would and should not happen for default:

Acme corp provides a URL short-linking service for its employees. I click on a short-link I receive from a co-worker and am prompted with HTTP authentication by Acme's short-linking service. The redirect occurs following this authentication. There is no reason the site being redirected to should require my credentials, and therefore it would be incorrect behavior for the browser to pass this information on (and in fact a security issue). Similarly, POST data should not be forwarded as it could only be intended for consumption by the pre-direct URL .

Get the final URL that the error came from so I can send another request.

Unfortunately, for security reasons, and standards definition, the standard XHR object (including the one Chrome uses for cross-site requests in extensions) does not provide any way to access the final URL which has an error. You can only access the final HTTP status and any data returned by the final URL.

--

Given this, you have a few options depending on how much control you have over the situation:

1) If you have control over the redirection server, consider including info. in your AJAX requests indicating an AJAX client, and have the server instead return data (i.e. a json object) indicating that a redirect should be made.

Or, if it is the intention to always pass on authentication data, consider implementing some mechanism for session-passing or including authentication info. in the URL being redirected to so the destination URL can consume this info.

2) If you have control over the destination of the redirect, consider including the URL of the destination when generating an authentication failure page. The XHR object will have access to this response data and can parse it to proceed with a new request.

3) If you have no control over either the redirection site or the destination site, consider hosting a proxying server to handle requests and catch 302's specifically.

http://myserver/?url=http://redirectsite.com&user=...&pass=...

4) If none of the above are options, the least desirable, yet viable option, is to build an NPAPI extension for Chrome that runs native code. This will give you full control over requests, and allow you to do pretty much anything. However, note this is at the expense of more complex development, potential security issues, and less user desirability.

like image 59
Rajiv Makhijani Avatar answered Nov 09 '22 15:11

Rajiv Makhijani