I have a database on an external server that I am trying to query. To do this, I am going on my local server (Tomcat) and creating an AJAX call (just the XMLHttpRequest object - I am not using any JavaScript libraries) to the page with a query appended. Pasting the exact same URL into Firefox causes it to try to download an XML document. My goal is to use AJAX to get that XML document.
The problem I am having is that when I make the call with AJAX, Firebug shows that the GET response returned 302 "Moved Temporarily" with a red X next to it. The header for the GET response has a Location parameter with OAuth authorization, and when I copy and paste the location parameter it takes me to the correct page (tells me to download the XML object).
EDIT: I tried it using jQuery's $.get("URL", function(data){alert(data)}); and the same thing happened - no alert, but a red GET request and 302 in Firebug.
Based on this information, I think that the database I am calling is first trying to redirect me to some OAuth thing, which then returns an authorized URL with which to access the database. This is what I should use to call the database, get the XML object back, and then do my thing. AJAX doesn't seem to be able to handle the redirect and is instead crashing.
I'm not sure this is correct, however, because I tried using the following code:
else if (xmlhttp.readyState == 4 && xmlhttp.status == 302){
alert("Hello 302!");
}
else {
document.getElementById("test").innerHTML = "On state: " + xmlhttp.readyState + "<br />HTTP Status: " + xmlhttp.status;
}
and it didn't give me an alert - instead it shows that it is on state 4 and status 0. I don't understand why it would return status 0. (Edit: Fixed the typo mentioned in answer 1 and nothing changed)
So my questions are:
What, exactly, is going on here?
What is the 0 status, why is Firebug giving me an X next to 302 in the console, and why isn't there a redirect?
How can I fix this?
Once I do fix it, will I be able to grab that XML file, or is there something else I need to do?
EDIT WITH UPDATE: It's a cross-site scripting issue. I went on the external server and ran the exact same script and was able to retrieve and parse an XML document containing the result of the query. The only obstacle is figuring out how to do this from an external server. I have access to the configuration of the external server and will be researching how to manipulate it to allow access via database queries from other sites.
Since it's an ajax request you can't pull data from another domain: http://en.wikipedia.org/wiki/Same_origin_policy
All you can do here really is request data from your own server (same domain) and have it pull data from the external db for you.
edit: this response is over 3 years old and now with modern browsers (not IE < 10) you can use Cross Origin Resource Sharing - https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
You have a syntax error readystate needs to be readyState. The way it is written, it will never be 4.
Another piece of advice would be to just check for a readyState of 4 and within that statement test for the status of 302. That way you will be able to troubleshoot whether or not it is the 302 that is causing your issue.
Try to do the redirection on the server side
Snapshot from FireBug
In this snapshot the Ajax request sent to server side (where there is the redirection)
Related
I have been using for long time the copy request action as described here:
(https://dev.onedrive.com/items/copy.htm) -
POST /drive/items/{item-id}/copy?access_token=...
(There is a small bug however, as it is a little bit different: POST /drive/items/{item-id}/action.copy?access_token=...) is the correct one.
From the Copy - POST request I was getting a url from Location response header: https:// onedrive.com/monitor/{monitor-id-...} to monitor the copy progress and when the status was completed, there was a response with the metadata of the new resource (e.g data.id, name, createdTime etc). I was doing a GET url request to get all these monitor details.
2 days ago I noticed there are some differences on the response of the API.
The url has a different format https://onedrive.com/monitor/{monitor-id-...}?access_token=..... When I am trying to make a GET using the url, I am receiving an API not found message.
When I am removing the access_token from the url and doing the GET request again, the new response is 200, but it is missing the data response with information about the newly created item.
To solve that issue, I need to getItem for the new item and get the metadata which adds more requests and more time for the copy action.
Any ideas why/ what happened exactly?
Thanks
Updated
This issue should now be resolved.
Original
This looks like a newly introduced bug in the service - as long as auth is provided the request to the monitor to 303 to a valid URL for the created resource. What's happening in this case appears to be a redirect to an invalid URL:
https://api.onedrive.com/v1.0/drives('me')/items('')?access_token=foo
We'll work on getting this fixed ASAP.
I hope i'm not being docile and missing something simple here but i'm stumped,
I need to check the response of a HTTP stream from the DI.fm audio streaming servers using Javascript for a chrome extension (Attempting to open a HTTP audio stream with a key is the ONLY 100% way to know if a key is valid for premium audio).
My intent is to validate a listen key (listen_key) and on 403 or 401 error, failover to a different URL.
The on error is fine and I can handle that using normal on error listeners, but the issue is that I'm using XMLHttp - So when a key is VALID, the stream begins to buffer without limit, Since it is receiving a HTTP stream. I can't find a way to drop out at this point and do a callback saying 200 OK :)
I don't want to have to set a timeout and failover if no errors within that time, as I want to be 100% certain that the error is Unauthorised. The unauthorised fallback will trigger a whole load of status variable changes for other things on the app.
I need to get the response being 200 and drop out as soon as that is confirmed.
Any other error (no data etc.) already falls back to a 3rd function which tries to reload the URL x number of times.
The element i'm getting this 200 status from can also be grabbed by loading the URL in an audio tag and then destroying the element if that's the only way to do it. Just not sure how to go about it best.
Your help is much appreciated :)
Phil.
I am trying to implement a simple request to Wikipedia's API using AJAX (XMLHttpRequest). If I type the url in the address bar of Firefox, I get a neat XML, no sweat there. Yet, calling the exact same url with:
// this is my XMLHttpRequest object
httpObjectMain.open("GET", "http://en.wikipedia.org/w/api.php?action=query&format=xml&prop=langlinks&lllimit=500&titles=kaas", true);
httpObjectMain.send(null);
returns an empty response. According to FireBug, I get a 200 OK response, but the content is just empty.
I suspect I might be missing something on the header of the GET http request.
Help! (and thanks!)
The Wikipedia API does support JSONP.
Your query string'll become something like this:
http://en.wikipedia.org/w/api.php?action=query&format=json&callback=test&prop=langlinks&lllimit=500&titles=kaas
But you'll have to build the jsonp handler (or you can use your favorite library to do it), switch to json output format from the xml you choose and create the callback function to parse the result and do the stuff you need on the page.
The browser will not allow you to send an XHR to another domain other than the one the page is on. This is for security purposes.
One way around this that I have seen is to setup a proxy on the domain the page is hosted on that will pass requests through to the actual api server. See http://ajaxpatterns.org/Cross-Domain_Proxy
I have an application in which most requests are submitted via AJAX, though some are submitted via "regular" HTTP requests. If a request is submitted and the user's session has timed out, the following JSON is returned:
{"authentication":"required"}
The JavaScript function which submits all AJAX requests handles this response by showing a popup message and redirecting the user back to the login page.
However, when a non-AJAX request receives this response the JSON is simply shown in the browser because the response is processed directly by the browser (i.e. the aforementioned JavaScript function is bypassed). Obviously this is not ideal and I would like the non-AJAX requests that receive this response to behave the same as the AJAX requests. In order to achieve this, I can think of 2 options:
Go through the application and convert all the requests to AJAX requests. This would work, but could also take a long time!
The JSON shown above is generated by a very simple JSP. I'm wondering if it might be possible to add a JavaScript event handler to this JSP which is run just before the content is displayed in the browser - I'm assuming this would never be called for AJAX requests? This handler could call the other JavaScript code that displays the popup and performs the redirection.
If anyone knows how exactly I can implement the handler I've outlined in (2), or has any other potential solutions, I'd be very grateful if they'd pass them on.
Cheers,
Don
3) Change your AJAX code to add a variable to the GET or POST: outputJson=1
You cannot add a handler to the JSP that way. Anything you add to it will make it a non-JSON producing page.
There are two options that I can see:
Add a parameter to the page by appending a URL parameter to the screen that modifies the output.
URL: http://domain/page.jsp?ajaxRequest=true
would output json only
URL: http://domain/page.jsp
would display a jsp page that could forward to another page.
OR
change the response to have the forwarding code in the JSP that will get executed by the web browser if it is hit directly. Then have your calling AJAX to strip the forwarding code out, and then process what is left.
4) Read up on the 'Accept' request HTTP header.
Then, on the server side tailor the output:
e.g.
if(Accept contains application/json...) { // client asking for json, likely to be XHR
return {"foo":"bar"}
} else { // other
return "Location: /login-please";
}
Start with a smarter error message, like this:
{"error":"authentication required"}
Wrap the JSON output in a callback:
errorHandler({"error":"authentication required"});
Have a handler waiting in your script:
function errorHandler(r) {
alert(r.error);
}
And don't forget to send it down as text/javascript and not application/x-json.
How do you get around this Ajax cross site scripting problem on FireFox 3?
If you're using jQuery it has a callback function to overcome this:
http://docs.jquery.com/Ajax/jQuery.ajax#options
As of jQuery 1.2, you can load JSON
data located on another domain if you
specify a JSONP callback, which can be
done like so: "myurl?callback=?".
jQuery automatically replaces the ?
with the correct method name to call,
calling your specified callback. Or,
if you set the dataType to "jsonp" a
callback will be automatically added
to your Ajax request.
Alternatively you could make your ajax request to a server-side script which does the cross-domain call for you, then passes the data back to your script
To update the answer (I guess, mostly for my benefit when I come looking for this answer later on), if are loading XML or something else, you can always ask the user if he will allow us to read from another site with this code:
try {
if (netscape.security.PrivilegeManager.enablePrivilege)
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
} catch (e) {
alert("Sorry, browser security settings won't let this program run.");
return;
}
(from the RESTful web services book) But, this only works in firefox, when the html file is loaded from local file. So, not that useful.
One more solution: if all you need is the headers, you can specify "HEAD" as the method and it won't trigger the security issue. For instance, if you just want to know if the web page exists.
var client = new XMLHttpRequest();
client.open("HEAD", my_url, false);
client.send(null);
if(client.readyState != 4 || client.status != 200) //if we failed
alert("can't open web page");
Some more details would be nice: which AJAX library are you using, what would you like to achive, how you do it.
For example it can be a cross-domain Ajax request, which is not allowed. In this case use JSON.
I came across this problem recently and it was while I as AJAX loading the local request, not cross site scripting problem. Also, Jimmy himself seems to have the same problem. This seems to be the FF security problem, this article describes the cause and the solution to access to restricted uri denied" code: "1012 problem.
Sorry, got that error using JQuery
$.ajax on FireFox 3. Tried jsonp
suggestion but I think that will only
work with something that will serve up
json. I'm trying to create a sample
local html file based mashup that will
pull data from Yahoo!Finance, but they
are serving .csv, so I think I'm SOL.
– Jimmy Chandra (Sep 9 at 17:20)
I hope you'll find it useful.