10

I want to do a fire-and-forget jQuery call to a web service.

Basically, I want to send a JSON object to http://myservice.com/uservisits/create and I don't care to receive any kind of return response. However, we want to use the same service for several of our domains, which means coming up against the cross-domain restrictions tied to Ajax.

How do you do this? There's a lot out there on JSONP and such, but I don't need to handle a response. I feel like I'm missing an obvious detail.

j0k
  • 22,600
  • 28
  • 79
  • 90
John
  • 3,332
  • 5
  • 33
  • 55
  • Not a duplicate. The link provided says " I need to grab and parse the response afterward." I don't need to parse the request. – John Oct 22 '12 at 20:15
  • 2
    right, but you can do it like that and just not parse the response... – ahren Oct 22 '12 at 20:16
  • I was hoping that by not needing the response that there would be a simpler approach. – John Oct 22 '12 at 20:17
  • @John: The provided duplicate has many in-depth answers describing how you can do this with/without caring about the response. – Andrew Whitaker Oct 22 '12 at 20:22
  • I agree, however there may be other, simpler solutions to when a response is not needed versus when one is. gilly3 has such an example below. – John Oct 22 '12 at 20:37
  • @AndrewWhitaker - I'm reminded of what Jeff said about *similar* questions in a [blog post regarding duplicates](http://blog.stackoverflow.com/2009/04/handling-duplicate-questions): "There’s often benefit to having multiple subtle variants of a question around, as people tend to ask and search using completely different words, and the better our coverage, the better odds our fellow programmers can find the answer they’re looking for". Often, keeping near duplicates open improves stackoverflow. Besides SEO, it's also useful when they show up as a "related" question on the right. – gilly3 Oct 22 '12 at 21:07
  • 2
    @gilly3: Closing a question will not magically remove it from search results. Also I never said that this was a *bad* question or that it should be *deleted*, I'm simply pointing out that I think it's a duplicate of a previously asked question. This question would still be "around" and locatable, it definitely still benefits the community. I would categorize this under #2 of the link you posted. – Andrew Whitaker Oct 22 '12 at 21:31
  • Also, @John, gilly3 could just as easily have answered the linked question. – Andrew Whitaker Oct 22 '12 at 21:33
  • 4
    One of the unfortunate aspects of StackOverflow is that it reinforces an aspect of our profession to bully those with less industry experience/knowledge/education/SO reputation points. I, the question author (aka the one in need of assistance), admit that the other question has value, but do not believe that it completely answers my question. My exchange with @Adam shows what I mean and I derive value from his follow up clarifications to my questions. Perhaps you believe that I should have been able to figure out the answer from the other question, but is that really your call? – John Oct 23 '12 at 15:21
  • 2
    The unfortunate aspect of closing a question that is NOT AN EXACT DUPLICATE is that it becomes impossible to add a new answer specific to this question that is not applicable to the other question. – John Oct 24 '12 at 17:33

3 Answers3

8

The easiest way to send an http GET request is with an image beacon:

var json = encodeURIComponent(JSON.stringify(obj));
new Image().src = "http://myservice.com/uservisits/create?JSON=" + json;

And, you can even get a little bit of information back by handling the load and error events. Of course, if the response is not an image, the error event will be called, and not load. You can set your service to return a single pixel image to solve that.

Edit: You mentioned you may prefer to use an HTTP POST. It's not nearly as simple as an image beacon, but you can make a cross-domain post using a hidden iframe:

var frame = $("<iframe>").hide();
frame.load(function() {
    var frameBody = frame.contents().find("body");
    var form = $("<form>", {
        action: "http://myservice.com/uservisits/create",
        method: "POST"
    });
    form.appendTo(frameBody);
    $("<input/>", {
        name: "json",
        value: json
    }).appendTo(form);
    form[0].submit();
});
frame.appendTo("body");

I think jQuery has something like this built in already. You might try digging through the jQuery.ajax documentation. If not, you could probably find a plugin that does it.

Community
  • 1
  • 1
gilly3
  • 87,962
  • 25
  • 144
  • 176
  • While this can be a good way to handle things, there's no way to handle error cases, As the OP doesn't appear to be concerned with response that may be okay. Alternatively, you can set "onError" handler on the image object, but there is no way to communicate actual error data back to the calling class, only handle generic errors this way. – FilmJ Oct 22 '12 at 20:29
  • @FilmJ - Of course. But, this question is about the specific case where you aren't going to parse the response. The image beacon approach is perfectly suited to this. – gilly3 Oct 22 '12 at 20:36
  • @FilmJ - Also, you could be very creative with error handling. A 1px by 1px image might indicate success. Any other image size could indicate an error code, decipherable by size. Or, an error message could even be displayed in the resulting image. – gilly3 Oct 22 '12 at 20:41
  • All of the answers given work and are appreciated. Long-term, I think CORS is the answer, but I'm not ready to do it today. I marked this as the "answer", because it offers a clever hack (browser support for images is as old as time) and an iFrame solution that will work if the service being called is RESTful. – John Nov 08 '12 at 20:41
2

The fact that you are not processing the response does not affect the same origin policy problem that you are facing. But, the fact that you will control all the consumers of the service opens up the possibility of using CORS. However, not all browsers support CORS. See the browser compatibility chart. If you need to support other browsers you still have to use JSONP.

Adam
  • 43,763
  • 16
  • 104
  • 144
  • By "use JSONP", do you mean just dataType: "JSONP" ? What does it mean to "use JSONP" if you don't have a callback? – John Oct 22 '12 at 20:25
  • @John It means using script element injection. Basically, all you need to do is create a script element on the page with the URL you want to hit as the source. Does your service need a POST or a GET request? – Adam Oct 22 '12 at 20:29
  • I can build the service to take either, though POST more correctly identifies that something is being done, not retrieved. – John Oct 22 '12 at 20:31
  • GET would be easier. Then all you have to do is use dataType jsonp. – Adam Oct 22 '12 at 21:08
  • so I just use $.get( ... dataType: "JSONP" ...) and don't include a callback and it will work? Is that it? – John Oct 22 '12 at 21:13
  • I think that will work to make a cross domain get request. Try it out. – Adam Oct 22 '12 at 21:14
1

The fact that you dont want any data back is actually irrelevant you still face the same cross domain problems. There are two ways you can go...

1) You can use jsonp (which actually makes a get request) to send the data across although this feels a little messy as you should try to use http verbs for their intention (ie GET should retrieve data).

2) You can use ARR (application request routing in IIS) to basically rewrite the request. So you would setup a rule for each domain to have a rewrite rule e.g. www.mydomain.com/webcall routes to http://myservice.com/uservisits/create where mydomain.com is the domain where the ajax call is being initiated. If you do this then you can use ajax in the normal fashion because as far as the browser is concerned you are now making requests on the same domain

Kevin Holditch
  • 5,165
  • 3
  • 19
  • 35