1

I'm writing a Google Chrome extension. I want to use jsonp cross-domain communication with jQuery. Here is the ajax code:

$.ajax({
    type : 'POST',
    url : $(this).attr('action'),
    data : $(this).serialize(),
    contentType: 'application/json; charset=utf-8',
    dataType : 'jsonp',
    success : function() {
        alert('A');
    }
});

This calls this URL:

http://sgsync.dev.kreatura.hu/api/signup/?callback=jQuery1710883696963544935_1327347078860&nick=&pass=&_=1327347087371

The server answers 200 OK with this data:

jQuery1710883696963544935_1327347078860({"messages":["Minden mez\u0151 kit\u00f6lt\u00e9se k\u00f6telez\u0151!"],"errorCount":1})

After that, i got this error message:

Can't find variable: jQuery1710883696963544935_1327347078860

I tried everything and i can't understand the problem. Please help me!

Note that i programed the server-side code, so there could be a problem with that too.

Thanks in advance!

Gera János
  • 95
  • 1
  • 7
  • 1
    Are you making this call within a `content_script`? – abraham Jan 23 '12 at 20:16
  • 1
    possible duplicate of [JSONP request in chrome extension, callback function doesn't exist?](http://stackoverflow.com/questions/8495825/jsonp-request-in-chrome-extension-callback-function-doesnt-exist) (this appears to answer the question) –  Jan 23 '12 at 20:41
  • @abraham: Yes, I'm making this call from a content script. – Gera János Jan 23 '12 at 20:51
  • @duskwuff This is exactly my problem. Unfortunately this doesn't answer my question. I'm making this extension for several web browsers (Opera, Safari, Firefox) and not every browser uses sandboxing. I tested this code on Safari, same problem there. And Safari not useing sandboxing. So there is got to be a way to overcome this problem. – Gera János Jan 23 '12 at 20:55

3 Answers3

2

Part of the reason this is so confusing is because jQuery API confuses the issue of Ajax calls vs JSONP calls. When using $.ajax with dataType: 'jsonp' this does not do an Ajax call (no XHR communication is used) it instead uses dynamic script injection with a callback. This means that the type: 'POST' will have no meaning (since dynamic script injection only works as a GET would work) and that all of the data will be encoded into the URL of the request as opposed to being send over as a post body. If this is truly intended to "POST" data then JSONP should not be used (since sensitive data will be sent in clear text).

As mentioned in one of the comments, this issue was addressed in this answer with regards to JSONP requests from Chrome content scripts and using XHR from a content script.

JSONP request in chrome extension, callback function doesn't exist?

With regards to Chrome Extensions, they do force you into a sandbox when using the "conten scripts" in a chrome extension. You can remove the dataType: 'jsonp' form the request in the Chrome Extension content script and this call should work. If that does not work, you might trying making the call directly using the XHRHttpRequest:

var xhr = new XMLHttpRequest();
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xhr.open("POST", $(this).attr('action'), true);
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
       alert("A");
  }
}
xhr.send($(this).serialize());

With regards to other browsers, I am not sure how each of their specific plugin enviroments handle making cross domain XHR calls (or if they even allow it in the first place). This is something that is NOT allowed from normal browsers (unless using something like easyXDM).

Community
  • 1
  • 1
Adam Ayres
  • 8,732
  • 1
  • 32
  • 25
  • Thanks for the answer, i realised now the problem. I just simply add the url of the target site into to permissions list and now it's working with regular AJAX requests fine. – Gera János Jan 24 '12 at 18:29
1

Have a look at this question and my answer as I think it might give you a solution...
Auto-load bookmarklet when in webpage as a Google Chrome extension

Community
  • 1
  • 1
PAEz
  • 8,366
  • 2
  • 34
  • 27
-2

Basic concepts of JSON-P:

Insert a script tag which loads an external javascript file.
That file does nothing else than execute a pre-defined function, with the data from the server.

How to make it work:

First create a function, bound to the global object (window):

window.processMyData = function processMyData(data) {
  console.log(data);
}

Then insert a script tag to the page:script = document.createElement("script");

$('<script></script>')
  .prop({'type': 'text/javascript', 'src': 'http://your.url?with=possible&data=in_it'})
  .appendTo('body');

You see? No need for the $.ajax wrapper, JSON-P works differently.

Good luck!

Edit: as a response to Duskwuff I would like to add that I don't mean to say $.ajax is bad, or not useful. I am not here to give you a jQuery code snippet, I am trying to let you understand your problem, with the help of a bit more basic javascript / html. JSON-P is not just JSON with a P added, it's completely different from a normal request.

  • The OP asked for help using jQuery's JSONP support, not a replacement which fails to handle failure, encoding the request, multiple requests 'in flight' simultaneously, or multiple different requests within a page. –  Jan 23 '12 at 20:33
  • @duskwuff I know but I am trying to give insight. Before using jQuery it is good to have a basic understanding of the problem. By giving this explanation, and this easier-to-understand example. – Lucas van Egeraat Jan 23 '12 at 20:38
  • 2
    Your "solution" doesn't help explain the problem, though. It's more or less the same as what jQuery does internally. –  Jan 23 '12 at 20:41
  • It doesn't? The problem is that the function is not in the global object. I am telling him a function should be pre-defined and within the global object. Didn't I explain the core of the problem? – Lucas van Egeraat Jan 23 '12 at 20:47
  • @LuukvanEgeraat I understand the basic concept of JSONP, but jQuery has some cool features that i want to use. Above duskwuff write down a potential problem source: sandboxing. But not every browser uses sandboxing, and my script doesn't work in Safari neither. – Gera János Jan 23 '12 at 20:59
  • 2
    You made me think. So if i'm define a function on the global namespace and pass the function name in the jQuery request, that actually can work. At least browsers that don't use sandboxing. – Gera János Jan 23 '12 at 21:02
  • @GeraJános Allright. Looking at the problem I would personally use a javascript bookmark instead of extensions, since you want your code to be run cross browser. Firebug uses this approach (but yes, there are also firebug extensions) – Lucas van Egeraat Jan 23 '12 at 21:05