views:

316

answers:

3

I've got a click tracking AJAX function (calls a WebMethod on an .aspx page), and I need to call it when the user clicks through to a link.

Unfortunately, I'm using window.location = "newUrl" to change the page, which seems to make the AJAX call fail. Is there a way around this?

I do not need to get any information back from the AJAX call, I just need to make sure the WebMethod is called.

I'm aware that I could just redirect on the success() or failure() calls, but then I would have to wait for the clickTracking() method to run, which takes ~ 1s. That is not acceptable by the agreement in the project spec, and so is not a viable solution.

+1  A: 

I just need to make sure the WebMethod is called.

If the above is really important, you can do the following:

function onLinkClicked() {
    $.ajax({
        url: 'WebMethod.aspx',
        success: function(data) {
            window.location = "newUrl";
        }
    });
}

There will be some latency from when the page will redirect. This may or may not be acceptable, depending on your application and on the average latency from your users to your host.


EDIT:

Further to the new comment below, unfortunately the window.location change will interrupt your AJAX request.

For internal links: You may want to track your links as soon as the users land on the new page, instead of when they click on the hyperlink.

For external links: I would use a server side redirect method, as Andy E suggested in another answer.

Daniel Vassallo
Ahem. I'll just edit the question with this one: 1sec+ page redirect times are not acceptable!
Ed Woodcock
And by the 'make sure it's called' thing, I mean make sure the call gets through to the web method, not wait for it to return.
Ed Woodcock
@Ed: Unfortunately the thing is that you can never be sure it got through, unless you wait for its return :)
Daniel Vassallo
@Daniel Yes, but it's not business critial, so if some get lost it won't be an issue. As for the tracking, we track view, click, popout and clickthrough (and some others). Our client likes data mining, they're in the retail industry!
Ed Woodcock
@Ed: I'm curious as well about other solutions, but I'd bet that Andy E's solution will turn out to be the most reasonable.
Daniel Vassallo
Also add `return false` after setting the `window.location` to new page.
Teja Kantamneni
@Teja: Why?....
Daniel Vassallo
@Daniel yes, quite probably. I've used that method of click tracking in other sites, but it's not quite good enough here.
Ed Woodcock
@Daniel Vassallo After setting the new Location, you want to make sure it is the last action to be done and prevent any other actions which may prevent from happening the redirect.
Teja Kantamneni
@Teja but then it won't redirect?!
Ed Woodcock
+2  A: 

Instead of using AJAX, why don't you just send the user to an ASPX page that records the click and then sends the location header to redirect to the new url? For instance, on link click, the following would occur:

window.location = "/redirect.aspx?track=true&url=" + encodeURIComponent(newUrl);

redirect.aspx would then handle both the tracking and the redirecting to the new URL. That's pretty much the only way you can do it without waiting for an AJAX request to complete before sending the user on their way.

See also: Redirecting Users to Another Page (MSDN)

It's probably worth noting that you see this method every day on many sites. Most commonly, they are found in ads. An AdSense ad link looks like this:

http://www.google.com/aclk
    ?sa=L&ai=C6DnFKnl1S5zhKoSBjAeqyKzKBPOD_2ehlIXfD9WsvQsQAVDQzK______
    8BYLvOuYPQCsgBAaoEGU_Q8k4OJin9jMDXAD6KQ_2Dsv7xyokLxRY
    &num=1&ggladgrp=13269254452699041863&gglcreat=8511532373602616220
    &sig=AGiWqtwzFm2sTimBuQpkD5kazyRNkkqH3w
    &q=http://www.amazon.co.uk/s/%3Fie%3DUTF8%26keywords%3Dhello%2Bworld

ish, anyway (I knocked it down a bit). When you click it, you land at http://www.google.com/aclk, which redirects you to the end site after tracking the click.

Andy E
Still not fully async, so I'd have to wait for the click method to complete, which would mess up the load time.
Ed Woodcock
@Ed Woodcock: I don't think it's possible to do this async without opening a new window. As soon as you navigate away from the page any current requests will be cancelled. The best solution IMO is the one that most sites use `yourpage.aspx -> redirect.aspx -> result url`.
Andy E
@Andy Yes, I've used it before, and it's not a bad solution, however I was hoping there was some sort of magical one-shot solution. You'd think there would be by now, given how prominent data mining is as a business marketing option.
Ed Woodcock
A: 

Use an <iframe> wrapper to wrap your pages. Then, when you have an AJAX request, pass the request up to the wrapper and navigate on the <iframe>. Doing this will give you the ability to have a perfectly asynchronous request while still maintaining app responsiveness.

Granted, you're also not changing the address bar and effectively killing your SEO, but that's the tradeoff for having a bad architecture. The fact that your click tracking function takes about a second is simply appalling. Perhaps you should start it on an asynchronous thread on the server and just serve the data to the client with a separate thread (System.Threading). That would alleviate the problems you're experiencing.

Otherwise, you can have asynchronous, reliable, or "not hacked together". Pick any two.

EDIT

My bad, you can also run your AJAX request as a popup:

window.open(url,'ajax','height=0,width=0');

It's still not a good idea, but it'll work.

mattbasta
I'm not sure I could stomach having an entire website wrapped in an iFrame, those things are evil. Plus, Google *hates* them for SEO purposes.
Ed Woodcock
@Ed Well, you really don't have much choice. Like I said, you can have any two of the three choices. I think this is an opportunity to work on back-end code more than it is an opportunity to hack together front-end code.
mattbasta