Question

I have a Grails controller action that is used for Ajax purposes, though you can still navigate and view the page in the browser.

class QuoteController {

def quoteService

/**
 * This page uses the ajaxRandom function defined below to display random quotes.
 */
def random = {
    def randomQuote = quoteService.getRandomQuote()
    [quote:randomQuote]
}

/**
 * I do not want this to be a valid page, but maintain its use as a simple Ajax method.
 */
def ajaxRandom = {
    def randomQuote = quoteService.getRandomQuote()
    response.outputStream << "<q>${randomQuote.content}</q><p>${randomQuote.author}</p>"
}
}

Is there a way to redirect if someone visits the URL via browser while maintaining the method's Ajax functionality from within a page?

Was it helpful?

Solution

def ajaxRandom = {
    if(!request.xhr) { // this calls the dynamic method request.isXhr()
        redirect action: 'random'
    } else {
        def randomQuote = quoteService.getRandomQuote()
        response.outputStream << "<q>${randomQuote.content}</q><p>${randomQuote.author}</p>"
    }
}

This works because most of the Ajax JS Libraries add the X-Requested-With header to the request. Grails add this isXhr() method dynamically to the HttpServletRequest class.

// test whether the current request is an XHR request
HttpServletRequest.metaClass.isXhr = {->
     'XMLHttpRequest' == delegate.getHeader('X-Requested-With')                
}   

OTHER TIPS

A simple way is to append a param to the url when calling it via ajax e.g. ?ajax=true

Then check for it and redirect if it's not there (such as when a use hits it with their browser).

If that is too easy to work around, inspect the request to see what is different between a browser request and an ajax request.

cheers

Lee

If you AJAX requests are always POSTS then you could check the method and assume a POST is an AJAX call because it's pretty hard for the average user to create a POST accidentally, where as they can always GET any URL (if they know of it)

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top