开发者

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 (th开发者_JAVA技巧is 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.


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.


Unfortunately there is no way to prevent xhr from auto-following redirects or set credentials for the redirect destination (it would be rather insecure anyway since that would allow the first site to redirect the credentials to any site, not only the one you want to get them).


You could try the type of solution described here: How to manage a redirect request after a jQuery Ajax call

That means in fact superseding HTTP protocol, you'll need to control the server as well. All ajax responses will be in code 200 (or at least the 3xx ones, not the 401/403) with a json object. and in this json object you can provide some special error code (why not reusing

Then you extends jQuery.ajax function to capture theses special codes in your json response and make the new requests needed. In fact the automatic jQuery redirect call is done by you and not by jQuery.

at first this seems ugly, but when dealing with problems like the one suggested in the link (end of session, redirect on login page) it seems that having a complete protocol handling in your ajax json communications between the client and the server is not a bad idea.


In case you control the server you may embed the data being lost in the redirect address itself. So xhr does a POST, and then does a GET with some of the POSTed data being encoded back (by the server) as GET params. No other solutions come up for me...


As Rajiv M. has stated above, you cannot catch 302 redirects using an XHL Object or AJAX request.

Your best bet is to setup a proxy of some kind in PHP/ASP or whatever server-side scripting language. The PHP script will simply follow 302 redirects until it reaches a final destination. Then, it can send the final URL back to your JavaScript page. Now future AJAX requests can be sent directly to the known final URL.

Or...

Your PHP script will just serve as a proxy. All requests will be sent to this PHP script.

Or...

Just hardcode the final URL into your JavaScript application, if possible (although I assume that it's not possible in your case).

Sorry -- I hate the "you can't do this" answers, too, but there are some JavaScript limitations that haven't quite been ironed out yet.


can't you use windows.location="newURL"? that used to work for me for redirecting

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜