0

I'm very new to JSON and JSONP.

I've read through each of the posts that are recommend by the SO search for this error, but I can't seem to get a handle on it.

I have the following code to grab data from an EXTERNAL website:

$.ajax({
    url: "https://url.com/authenticate?login=test&apiKey=test",
    dataType: 'jsonp',
    success:function(json){
      console.log("login successful");
      }
  });  

When I load the page, I get:

Uncaught SyntaxError: Unexpected token :

and when I click on the error in Chrome, I see

{"Status":{"Code":"2","Message":"Authentication Succeeded","Success":"true"}}

with a little red x after "true"})

From this, it seems as though I have succeeded in logging in, but I'm doing something else wrong because my console.log("login successful"); never fires. What am I doing wrong?

P.S.

I've tried dataType: 'json' but I get the No 'Access-Control-Allow-Origin' header is present as I'm on a different server, so I went back to jsonP as this is cross-domain.

I've also tried the above url as url: "https://url.com/authenticate?login=test&apiKey=test&callback=?", as I've read I need a callback, but I don't really understand what the functionality of callback is and either way, the error that gets returned (whether &callback=? is in there or not) is:

authenticateUser?login=test&apiKey=test&callback=jQuery111107732549801003188_1423867185396…:1 Uncaught SyntaxError: Unexpected token :

so it's adding the callback in either way....

Also, from the API I'm trying to access: "this uses the REST protocol, and provides data structured as XML or JSON"

This is not a duplicate of the linked post as the information in the linked post does a great job of explaining what JSONP is, but doesn't answer my specific question regarding why I get data back (so my call is successful,) but why I still get an error and cause my script to stop.

Brian Powell
  • 3,336
  • 4
  • 34
  • 60
  • 1
    This isn't really a duplicate question - I read through the entire post you linked, and there's some great info it, so thank you. Still, I say it's not a duplicate because my question is not answered anywhere in that post. – Brian Powell Feb 13 '15 at 23:00
  • The answer to your question can be derived from the other question: JSONP is nothing else but dynamically evaluating JavaScript received from the server. The response you receive is not valid JavaScript, hence you get that error. – Felix Kling Feb 14 '15 at 00:04
  • Logout and go directly to the URL from browser and see what it returns – Anthony Feb 14 '15 at 01:44
  • You get the error because it is NOT JSONP. That is JSON. – epascarello Feb 14 '15 at 01:44
  • @FelixKling Thank you for your response, I really do appreciate it. Would you possibly be able to help me understand why the response is not valid JavaScript? My code looks exactly like much of the code I've seen in other posts and tutorials, and the data I'm getting back from the server is exactly what I get when I type this URL directly into the address bar, so it's working technically... – Brian Powell Feb 14 '15 at 01:44
  • If the 3rd party does not support JSONP and it does not have CORS enabled, than there is nothing you can do with your JavaScript call. You are going to have to use a proxy. – epascarello Feb 14 '15 at 01:47
  • @epascarello , so am I going about this entirely the wrong way? The webpage says `"this uses the REST protocol, and provides data structured as XML or JSON`. They obviously developed the API to be used by people outside of their domain, so it makes no sense that I can't write something to connect to it and get data. Is an AJAX call utilizing JSON the wrong way to get data back? – Brian Powell Feb 14 '15 at 01:56
  • FWIW: just type `{"foo": "bar"}` into the console, you will get an a syntax error. That's because `{...}` is interpreted as a block. Plain JSON by itself is not valid JavaScript. – Felix Kling Feb 14 '15 at 07:32

1 Answers1

1

The API you're sending the AJAX request doesn't implement JSONP. It ignores the callback= parameter, and just returns ordinary JSON. But when the browser tries to process this as JSONP, it gets a syntax error because it's not properly formatted. JSONP is a JSON object wrapped in a call to the specified callback function, e.g. it should be sending back:

jQuery111107732549801003188_1423867185396({...});

where {...} is the JSON object you're trying to retrieve. But it's just returning {...}.

You should implement this using a PHP script on your own server. It can be as simple as this:

<?php
$username = urlencode($_POST['user']);
readfile("https://url.com/authenticate?login=$username&apiKey=test");

Then your AJAX call would be:

$.ajax({
    url: "yourscript.php", 
    type: "post",
    dataType: "json",
    data: { user: "test" },
    success: function(json) {
        console.log("login successful");
    }
});
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • This makes no sense to me though. This is a company that my company works with who specifically gave me access to their API. If they don't support JSONP, how am I supposed to use the API??? And if JSONP isn't supported, why do I get back a string that shows my session authenticated? – Brian Powell Feb 14 '15 at 01:52
  • You're still sending the request to the server, just as if you were submitting a form, so it performs the authentication normally. You just can't read the response, because it's not coming back in the correct way. The browser blocks cross-domain AJAX responses. JSONP is a trick, instead of the browser trying to read the response using AJAX, it creates a ` – Barmar Feb 14 '15 at 01:56
  • The whole point of this is that the server has to take special action to allow the API to be used from another domain. Either it adds your domain to its `Access-Control-Allow-Origin` header, or it has to implement JSONP. – Barmar Feb 14 '15 at 01:57
  • Okay, I'm happy to go back to my contact and ask to be added to the `Access-Control-Allow-Origin` header, but I want to make sure that's my only option for solving this so I don't look stupid....... It kinda seemed like when they gave me the username and password to access the API, that was all I would need, especially since the command works from the address bar just fine. – Brian Powell Feb 14 '15 at 01:59
  • 1
    You probably shouldn't be doing it directly from the browser, because then the API key will be visible to the user. You should use the API from a script on your server. – Barmar Feb 14 '15 at 02:05
  • oh totally - I was saying that if I go type in the exact same thing as my code says into the browser, I get back the response I'm looking for. Inside my code, I'll have it (eventually) inside a separate .js file with some other code so it's hidden from the user, (and it's organized better with my other scripts...) – Brian Powell Feb 14 '15 at 02:08
  • 1
    All `.js` files are visible to the user. Open up Developer Tools, go to the Sources tab, and you can see them all. – Barmar Feb 14 '15 at 02:09
  • so inside a php script then, (I'm assuming that's how I would do something `on the server` – Brian Powell Feb 14 '15 at 02:10
  • Yes. If you do it there, using `cURL` or `file_get_contents`, it should work just fine. – Barmar Feb 14 '15 at 02:11
  • by `it` do you mean `the whole getting data out of the API` thing? Cause if so I'm going to read up on both of those things right now! – Brian Powell Feb 14 '15 at 02:13
  • dude, thank you so much for taking time out of your day to help me with this. I really appreciate it! – Brian Powell Feb 14 '15 at 02:20
  • so doing it this way, I'm getting an output in my php file of `2Authentication Succeededtrue`, but my script is still failing... I have: `$.ajax({ url: '/login.php', dataType: 'JSON', type: 'POST', success: function() { console.log("BOOYA"); }, error: function() { console.log('Uh Oh!'); }, }); ` and in my php file I just have the username and password defined there. – Brian Powell Feb 14 '15 at 02:50
  • I've also tried this using your exact code, (modified URL of course...) and I get the same result, (of no `console.log` as there's no error call) – Brian Powell Feb 14 '15 at 02:56
  • alright - I dug into the response and found that it's XML, (even without the &fmt=XML` flag... not sure why they're responding in XML by default, but I changed the datatype to XML and it WORKS!!! yay! Thank you times 1000. – Brian Powell Feb 14 '15 at 03:00