Check for 200 Response of an XMLHTTP 'Stream' with Javascript - javascript

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.

Related

SoundCloud Api redirect confusion and Audio Api Streams

I am attempting to make a request to the SoundCloud API. Then when I get the response I set the stream_url as the source of an < audio > element.
This works:
http://matthiasdv.org/beta/
But not always... When you search for 'Bonobo' for example, you can play the first few tracks without any issue. But when you try to play 'London Grammar - Hey Now (Bonobo remix)' - the 7th result - it won't play. It throws no errors whatsoever.
I've been tinkering around with Chrome's webdev-tools and under the network tab I see the requests being made. I found that tracks that DO play have a short Request Url, like this:
https://ec-media.sndcdn.com/vR5ukuOzyLbw.128.mp3?f10880d39085a94a0418a7ef69b03d522cd6dfee9399eeb9a522029f6bfab939b9ae57af14bba24e44e1542924c205ad28a52352010cd0e7dd461e9243ab54dc0f0bba897d
And the ones that don't look like this:
https://cf-media.sndcdn.com/8PCswwlkswOd.128.mp3?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiKjovL2NmLW1lZGlhLnNuZGNkbi5jb20vOFBDc3d3bGtzd09kLjEyOC5tcDMiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MzM0Mjc2MDN9fX1dfQ__&Signature=cD-XVhnvQnIATkfrBDDVy0Q7996C8DymwxRLwBBduab0~L0MynF1ftcMky~21T8Q-gCZ2~dMK8dz7uVxvJTIJgXPxEZvhNtbvescMK6iFMg-xSAty-4OhJYjrIZJ2j8NE4uNA4Ml7MWbWcQw4KtUtpZitOQuguS3DPFDII3VF-dvzb2L~xG-G8Uu3uOnI1WhnAAfhf1QWMO7swwB89HtcCiuVBmfluG28ELrJEq-au8mqIMB3sLTno6nUuTtpHXR2ayXBsYcYLLJVXa3Ul8p1rhLS5XWHKWXY8xug4jwey27~C5PVAomK6Z5lJx-mz-0zYs4riUYtl0zACbZ1OfwTQ__&Key-Pair-Id=APKAJAGZ7VMH2PFPW6UQ
Now at first glance I figured it was an encoding issue, but wrapping a quick encodeURI() around the ajax url did not work.
Furthermore I do not understand where these urls come from. In my code I am directing my ajax request towards, for example:
https://api.soundcloud.com/tracks/140326936/stream?client_id=5c6ceaa17461a1c79d503b345a26a54e
Thus, the request url in the GET request (as found under 'network' in Chrome's webdev tools) makes no sense to me. Is SoundCloud redirecting get requests to a CDN-host? One more thing I've noticed is that each time TWO requests are fired instead of one. The first one is always canceled and contains a 'Provisional headers are shown' warning. I believe this is because I am setting crossOrigin = "anonymous", otherwise certain browsers would not load the content.
What I guess may cause the problem is that when the url is set as the src attribute of the element an evenListener is fired in the dancer.js library, which handles the Audio Api and the playback (https://github.com/jsantell/dancer.js/). It may be that encodeURI() is required somewhere in the library.
I decided to ask the question anyhow because I don't understand how the Request Urls's above are formed and why two, instead of one, requests are being fired and why the first is always cancelled.
Any hints which my solve the playback issue are more than welcome too...
When you run the request for
https://api.soundcloud.com/tracks/140326936/stream?client_id=5c6ceaa17461a1c79d503b345a26a54e
you get a HTTP 302 Found response from the server, which is a URL redirect (http://en.wikipedia.org/wiki/HTTP_302). This will cause your browser to load from the new URL that the server returns, and thus the two requests you see. The server basically says "yeah, I know where to find that file, ask that guy over there".
The reason why one works and the other not, I'd think, is that https://ec-media.sndcdn.com has the Access-Control headers set while https://cf-media.sndcdn.com doesn't. This is an issue with the server configuration and unfortunately nothing you can control from the client side. Dunno if it's a deliberate move by soundcloud or if it's something you could ask them about.

Determine source of API request?

I have been introduced to a web application that I need to make some modifications to.
The app is huge, and there are perhaps 100 Javascript files. These files send requests to a third party API all the time.
Now, in the console, I can see all these requests. Let's say that one looks like:
GET http://123.456.789.10:8000/v1/accounts/accountnum/children?_=1422026843600
Then of course I can see the parameters sent, headers and response. My problem is that I need to locate the JS file which is sending one particular request. Searching all the files for the API target URL reveals that 40 or 50 files send requests to this same URL, with similar parameters.
Is there a way I can find out the source file of one specific request? Something like sent from filename.js on line 123 would be ideal, but just the file name would be of great help too.
I could go through all the files and try each one individually, but that seems like a huge waste of time. There would be A LOT of code to go through.
If you know what to do in the application to make the request occur, in Chrome you can use an XHR breakpoint to catch it:
Navigate to the point where you're about to do the thing that causes the request
Open Dev Tools
Switch to the Sources tab
On the right, scroll down to "XHR Breakpoints"
Click the + button, fill in some appropriate subset of the URL (or leave it blank to break on all XHR)
Add it
Do the thing that does the request
Chrome will break and take you to the line of code that was triggering the XHR.

Using GWT, how to load an image and access image attributes & http status codes

Using GWT I am loading images from a server I do not control. Currently, I use GWT new Image( url) and then use ImageHandlers and ErrorHandlers to catch what happened and put the images in my buffer and the DOM. Then I make the images visible sequently to animate the process. But now I need a bit more, I need to know the error code, e.g.304 that the server returned for the image and also I need to get at the header response attribute, 'Last-modified'. For 304, I know I need to resubmit the request later when the server will have created a new version ( with exactly the same url ) which I think I can manage, but it will then have a new 'Last-modified' and I need to know that DateTime.
By using new Image(url), I am letting the browser do the loading, but I don't know how to get at the details of the load.
Q1:Is there a way to pull more info from an image?
GWT Image just seeems to wrap a JS object. I look in Firefox Console-Network, but don't see much detail there either. Is Last-modified and error code forgotten by the time it gets (or doesn't) in the DOM tree.
If the answer to Q1 is no the information is gone or inaccessible, ..
Q2: Do I need to stop using the browser to fetch images and do it with an XmlHttpRequest and then presumably I have access to the response codes and the header attributes. SOP is not an issue. But how then do I get from say the Response OutputStream to an Image? Do I have to Base64 encode it or is there a better way? Will one of the other non-url constructors for image help, say Image(Element) or Image(ImageResource). Then the issue becomes how to make a response stream into a Element or ImageResource?
Note: This other question 'How to print error message of why image failed to load?' is related, but doesn't get to an answer.
Getting Error codes, and getting the response as a stream must be done with an HTTP client (GWT has the built in RequestBuilder). You can also try to get the error code with native JS, using the method described here.

AJAX not handling 302 redirect

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)

Twitter widget doesn't always populate

I am displaying a Twitter feed from their feed widget on my website. Sometimes the widget likes to not display any information. I figure this is because the API is overloaded. Regardless, is there any known way to display an error message in the event that Twitter can't load my feed? Has anybody else experienced these issues?
Firstly use a suitable http recording proxy for your OS (Fiddler2 is fantastic if you are on windows), shift F5 the page until you get the fault.
Filter the log for hosts widgets.twimg.com or api.twitter.com... This diagnoses the failure point because:
If the js (or css) request to widgets.twimg.com fails (Look for a 404 or truncated text), then the javascript failed to fetch. Unlikely since files should be static.
If the api.twitter.com request is missing, then the javascript failed to run.
If the api.twitter.com request occurs, but there is a failure in the response (bad response code or response looks whack) then the twitter api is failing to give you the feed.
For detecting 1 in javascript, you can detect the failure to load by using a timeout, and onload check that it loaded (simple check is that window.twttr exists - however not a great test because that gets set at top of javascript, so only confirms that javascript syntax was valid and started running). (Might need onreadystate to detect load for IE?)
<script src="http://widgets.twimg.com/j/2/widget.js" onload="twitterloaded()"></script>
For detecting 2, run page with debugger.
For 3, from a quick look at the code, looks like the code retries requests to the twitter api (you might want to look ath the configuration settings for the api) and it looks like there are api variables to check if everything is running e.g. TWTR.Widget.isLoaded _isRunning and _hasOfficiallyStarted.

Categories