XMLHttpRequest gives Invalid state when using Last.fm API - javascript

I'm trying to integrate scrobble support into Ubuntu Touch's music app, but I have some difficulty since I can't seem to get the session key working.
In request() I get "Error: Invalid state" on row 53. It seems like last.fms API doesnt answer correctly, nor has the correct state, but I'm new to XMLHttpRequest, so I'm not sure what's the matter.
Code: http://pastebin.com/Aa6DVUA1

You're executing encodeURIComponent with the complete URL instead of the individual query arguments, thus resulting in something like https%3A%2F%2Fws.audioscrobbler.com%2F2.0%2F%3Fmethod%3Dartist.getsimilar%26artist%3DKiss... which is clearly not a valid URL. For an example see here.
Secondly, your usage of XMLHttpRequest is wrong, XHR operates asynchronously but you never define a callback function for your request. Querying xhr.readyState and xhr.status immediately after invoking send() will be executed before the request actually finishes. See here for how to use XHR.
PS: Why not use one of the existing API wrappers for JavaScript, i.e. http://lastfm.felixbruns.de/javascript-last.fm-api/ or at least jQuery to handle the XHR?
PPS: Your authentication request will not work, as you are required to submit the arguments in the post body as opposed to the query string, see this forum post for more information.

Related

avoid HTTP GET after successful HTTP DELETE done through angular $resource

Looking at the developer tools of my browser I noticed my application is doing an unnecessary HTTP GET request after a successful delete operation done through $resource.delete.
On the angular documentation for resource I can see
"Success callback is called with (value, responseHeaders) arguments, where the value is the populated resource instance or collection object. The error callback is called with (httpResponse) argument."
so it looks like that is why is doing the request.
My issue, though, is that this happens on successful delete operations, so the GET request always returns an empty 200 OK.
I'd like to avoid having this extra HTTP GET request on successful delete operations; does anybody know how can I achieve this?
I do want to use a success callback function, but I don't need the value of the deleted object (in fact there is no value since the HTTP GET returns no content).
Probably, this is how you have implemented your code. Angular doesn't make any GET requests after the DELETE requests until specifically made.
You may want to verify again yourself, else I would request you to show your requests.
Hope this helps!!

JavaScript Get Data From Other Site

I'm fairly new to JS and have a question. Would it be possible to pull data off from another website to use in your own? For example, say I have a JS web app that lets a user input their Twitter username and then the script goes to this username and looks for the follower count element and pulls that number off to display back in the web app. I'm sure there are APIs and such to do something like that specific Twitter example, but I'm getting more at the general idea of being able to access data on other sites. How can it be done? Surely there is a way if my browser can access all of that information, right? Would you have to put an invisible iFrame into the app and search through it with JS?
To put it in basic terms for a newbie, this is only possible if the website in question has an API, specifically designed to allow outside access. Sometimes they're pretty easy to understand and set up.
Accessing the content of an outside website in a way it wasn't really designed to support has happened, but it's usually what's known as "hacking". It's sometimes easy to do for very basic types of sites, but most sites that request login information forbid it. (Except through aforementioned APIs). The biggest concern is that if someone is already logged in to Twitter on their browser, an outside site of questionable origin could automatically post bad things to your account while you're not even apparently visiting Twitter.
Yes, it's possible.
The best approach is to use ajax (Asynchronous JavaScript and XML) with jsonp (Javascript Object Notation with Padding) datatype.
To use this method the server you are going to connect should be expecting the request so it can response with jsonp (it's just a json data wrapped by a callback function you defined when you make the request).
The process:
1) Your code make an ajax request to the other server adding a callback function to the url. It's very commom to use "callback" param name, but the server can define the variable name it prefers.
http://other-server-url.com/?callback=myFunction
A good and easy approach here is to use jQuery. If you define dataType:"jsonp" in your ajax call, jQuery handles the process of appending the callback and execute the right function when you get the response. It's a good idea to take a look at jQuery's ajax docs and read a little about jsonp cross domain requests.
$.ajax({
type: "POST",
dataType:"jsonp",
url: "http://other-server.com/",
data: { name: "John", location: "Boston" }
}).done(function( msg ) { // this function will be executed when you get the response
alert( "Data Saved: " + msg );
});
this jQuery method only works if the param name is callback. If it isn't, you should handle by your own, or take a deeper look at documentation to know how to do it with jQuery.
2) The server should be waiting for these "callback" param and response your request with a jsonp data format. It's just json data format wrapped by the function you passed as the callback. Like this:
myFunction({ json-data });
3) When you get the response, the myFunction function will be executed automatically, with the json data as the parameter:
function myFunction(myData) {
console.log(myData); // this will log the data on the browser console
}
I hope I have helped. Good coding.

Passing reference to XBMC json-rpc to identify answer later

I am using XBMC json-rpc with websockets. When I send json request like "method":"Playlist.OnClear" I get response {"id":1,"jsonrpc":"2.0","result":"OK"}.
So if I'll send multiple requests I will get multiple responses and I won't be able to identify which response refers to which request. Is it possible to pass some additional data to request so that it would be added to response (like context in jquery ajax call)?
I don't know is it related to XBMC or json-rpc in general.
Perhaps this question was not answered because it is slightly inaccurate.
Firstly there is no method "Playlist.OnClear, rather Playlist.OnClear is only a non-solicited notification from the media player, on that states the playlist was cleared.
Now the playlist might clear directly as a result of another request you had made, for example Playlist.Clear comes to mind, which is indeed a method.
So when you send the valid json packet
{"jsonrpc":"2.0","method":"Playlist.Clear","params":{"playlistid":0},"id":10101}
You can use the "id" key to add a, guess what, an id to the request, and that very same id will be returned from the mediaplayer
{"id":10101,"jsonrpc":"2.0","result":"OK"}
Furthermore, it is possible to write paired web based requests/response code, but that's not even necessary considering the above...

Does d3.json() support authentication? If not, what other JavaScript options are available for JSON retrieval?

I am developing an application that needs to gather information from GitHub, so I began looking at their API. My initial thought was to use the d3.json() function to get the data (because it's simple and has done good things for me in the past), but there doesn't appear to be a way for me to authenticate with that function. For example, $ curl -u "username" https://api.github.com is given as an example of basic authentication (from GitHub API--obviously they use curl for their examples).
So, is there a way to do authentication with the d3.json() function? And if not, what are my other options to get the JSON with JavaScript?
Thanks!
Edit:
I'm experimenting now with using jQuery's getJSON method as shown here, because I started getting the error "XMLHttpRequest cannot load url Origin url is not allowed by Access-Control-Allow-Origin." Of course, the switch doesn't help with the ability to authenticate, but I can at least get the public data (which is most).
Edit #2:
Has anyone experimented with michael/github or fitzgen/github-api? I'm going to start looking into those.
If you have a PHP script which echos JSON, you can do all authentication server-side. Note that you can also send a GET request to your PHP script, so the way you call your script can be dynamic.

Any way to identify a redirect when using jQuery's $.ajax() or $.getScript() methods?

Within my company's online application, we've set up a JSONP-based API that returns some data that is used by a bookmarklet I'm developing. Here is a quick test page I set up that hits the API URL using jQuery's $.ajax() method:
http://troy.onespot.com/static/3915/index.html
If you look at the requests using Firebug's "Net" tab (or the like), you'll see that what's happening is that the URL is requested successfully, but since our app redirects any unauthorized users to a login page, the login page is also requested by the browser and seemingly interpreted as JavaScript. This inevitably causes an exception since the login page is HTML, not JavaScript.
Basically, I'm looking for any sort of hook to determine when the request results in a redirect - some way to determine if the URL resolved to a JSONP response (which will execute a method I've predefined in the bookmarklet script) or if it resulted in a redirect. I tried wrapping the $.ajax() method in a try {} catch(e) {} block, but that doesn't trap the exception, I'm assuming because the requests were successful, just not the parsing of the login page as JavaScript. Is there anywhere I could use a try {} catch(e) {} block, or any property of $.ajax() that might allow me to hone in on the exception or otherwise determine that I've been redirected?
I actually doubt this is possible, since $.getScript() (or the equivalent setup of $.ajax()) just loads a script dynamically, and can't inspect the response headers since it's cross-domain and not truly AJAX:
http://api.jquery.com/jQuery.getScript/
My alternative would be to just fire off the $.ajax() for a period of time until I either get the JSONP callback or don't, and in the latter case, assume the user is not logged in and prompt them to do so. I don't like that method, though, since it would result in a lot of unnecessary requests to the app server, and would also pile up the JavaScript exceptions in the meantime.
Thanks for any suggestions!
When using the AJAX methods within jQuery, it should be setting a header of 'X-Requested-By: XMLHttpRequest' in the request.
My initial thinking would be that you could check and see if that header is set on the server side, and if so, instead of issuing a redirect, send back some JSON with a redirection URL, and have the client JS look for the presence of that redirection in the response, with the server only issuing the redirect when it's not an AJAXy call.
According to the jQuery documentation if you don't specify dataType as script, as you are doing now, it'll try to figure out what the response is based on the MIME type. You could then also add an option called dataFilter to the $.ajax method; it is a function which takes two parameters, dataFilter(data, type) and type is the data type as determined by jQuery, you can look at the type and procede accordingly.

Categories