0

First, I've read many posts here but haven't found the issue in my own code, including this one $.ajax and JSONP. ParseError and Uncaught SyntaxError: Unexpected token :

I'm building a Safari extension and need to post/get to my server and handle the response. Safari is throwing this error:

SyntaxError: Unexpected token ':'

and this message

"handle was not called"

where 'handle' is the callback in this Extension code:

var server="http://localhost:3001/api/login";
$.ajax({
       type : "GET",
       url :  server,
       data: {"something" : "else"}
       dataType: 'jsonp',
       jsonp:false,
       jsonpCallback: 'handle',
       success: function(data, text){
        var json = $.parseJSON(data);
        console.log(json)
       },
       error: function (request, status, error) {
        console.log(error );
       }  
});

and the Express.js (2.5.5) code is:

//in the config
app.set( "jsonp callback", true )

app.all('/', function(req, res, next){
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});

app.get('/api/login', function(req, res){
res.json(
  {
    "success": {"that":"this"}
  }
);
});

NOTES: I've tried res.jsonp, setting content types, etc, with same response. I've learned a TON about CORS and Ajax in the process, but my eyes are clearly bleary. Clicking my heels three times hasn't helped either.

Clues? Thanks!

Community
  • 1
  • 1
bear
  • 1,318
  • 5
  • 16
  • 26

1 Answers1

2

By setting dataType: 'jsonp', it will already parse the JSON for you. jsonp: true is incorrect. This combo should work:

JSONP

$.ajax({
   url : "http://localhost:3001/api/login",
   data: {"something" : "else"},
   dataType: 'jsonp',
   success: function(data){
     // It is already an object, don't parse it again.
     console.log(data)
   },
   error: function (request, status, error) {
     console.log(error );
   }  
});

with

app.get('/api/login', function(req, res){
  res.jsonp({
    "success": {"that":"this"}
  });
});

// Remove this:
app.set( "jsonp callback", true )

CORS browsers and JSON:

$.ajax({
   url : "http://localhost:3001/api/login",
   data: {"something" : "else"},
   dataType: 'json',
   success: function(data){
     // It is already an object, don't parse it again.
     console.log(data)
   },
   error: function (request, status, error) {
     console.log(error );
   }  
});

and

// This is 'app.use', not 'app.all'.
app.use('/', function(req, res, next){
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});

app.get('/api/login', function(req, res){
  res.json({
    "success": {"that":"this"}
  });
});
loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
  • thanks--tested your first example: that leads back to my other Q you commented on, got the double function again: jQuery19108954158783890307_1364399791627 && jQuery19108954158783890307_1364399791627({ "success": { "that": "this" } }); testing the others... (also, comma missing from the answer, will edit – bear Mar 27 '13 at 15:58
  • the second example gives this error (this is an extension): XMLHttpRequest cannot load http://localhost:3001/api/login?something=else. Origin http://www.example.com is not allowed by Access-Control-Allow-Origin. I've set the extension permissions to allow all websites... Permissions Website Access Include Secure Pages Level All – bear Mar 27 '13 at 16:01
  • @bear I don't know much about Safari extensions unfortunately. Where is `example.com` coming from? – loganfsmyth Mar 27 '13 at 16:08
  • example.com is just my localhost. The extension grabs data from whatever site you're on currently and posts it back to that endpoint. – bear Mar 27 '13 at 17:46
  • @bear Are you actually using 'example.com' in your code? That hostname is reserved. – loganfsmyth Mar 27 '13 at 17:52
  • I am not--just popped it in there for this. Using localhost. – bear Mar 27 '13 at 18:15
  • @bear Oops! Found the issue. You are using `app.all` instead of `app.use`. `all` is equivalent to using `.get`, whereas `.use` binds middleware to run before handlers. – loganfsmyth Mar 27 '13 at 18:48
  • that's not it... really must be something in the extension. It might be that I should use the background page in the extension... @loganfsmyth – bear Mar 27 '13 at 19:08
  • @bear Weird. I tried it out locally and after I changed that it worked for me. Can you confirm if you open up `/api/login` in your browser, you get the proper access-control headers? Maybe there is something more that the extension needs. – loganfsmyth Mar 27 '13 at 19:19
  • awesome tip, let me do that. I should've curled... but also am having some luck with running the script in the background page. – bear Mar 27 '13 at 19:43
  • yes--works in the browser. Definitely an extension issue. Thanks! giving you props...@loganfsmyth – bear Mar 27 '13 at 19:44
  • loganfsmyth now I'm able to just use straight json...using extension background page, which is treated as safe by Safari. I then have to communicate with the injected script through the safari api, which is the next bit of fun. You were a huge help though--really learned a lot so thanks. – bear Mar 27 '13 at 19:51