[web-devel] Getting the http request header in Yesod?

Rehno Lindeque errantkid at gmail.com
Mon Sep 27 22:17:00 CEST 2010

On Sun, Sep 26, 2010 at 12:20 PM, Michael Snoyman <michael at snoyman.com> wrote:
> On Sun, Sep 26, 2010 at 10:10 AM, Rehno Lindeque <errantkid at gmail.com> wrote:
>> One more question. Is it possible to manipulate the request header
>> when doing a redirect? For example, at one I have (redirect
>> RedirectTemporary $ AuthR LoginR), but "X-Requested-With" isn't being
>> passed through...
> No, the request headers are set by the browser, and you can't directly
> affect them. What you *could* do is set a session variable or
> something. However, your best bet is probably to redirect to a URL
> with a query-string parameter indicated the request-with information
> and then check both the request header and the query string parameter.
> Michael

Thought I'd mention that this worked out very nicely in Yesod. I
modified the default layout to return only the page contents of a
request if it is an ajax request, but add all the surrounding html if
it isn't. I also used a session variable for the redirected ajax
requests. At first I just wanted to call the correct handler directly
instead of redirecting if it was a ajax request but since getLoginR is
private to Yesod.Helpers.Auth I had to redirect and the session
variable was actually very simple to set and check.

I.e. If anyone is curious it looks like this:

> isAjaxRequest :: GHandler master sub Bool
> isAjaxRequest = do
>   request    <- waiRequest
>   sessionVar <- lookupSession Session.ajaxRequestKey
>   return $
>     (isJust $
>       listToMaybe $
>         filter (\(k,v) -> k == mkCIByteString "X-Requested-With" && B8.map toLower v == "xmlhttprequest") $
>           requestHeaders request)
>     || isJust sessionVar
> instance Yesod  where
>     defaultLayout widget = do
>         mmsg  <-  getMessage
>         mAuth <-  maybeAuth
>         -- Get the page contents
>         pc    <- widgetToPageContent $ do
>             widget
>             addStyle $(Settings.cassiusFile "default-layout")
>        -- Check whether this is a ajax request
>         isAjax <-  isAjaxRequest
>         deleteSession Session.ajaxRequestKey
>         -- Return either the page body if it's an ajax request or embed in the default layout if it's a normal request
>         hamletToRepHtml $
>           if isAjax then pageBody pc
>           else $(Settings.hamletFile "default-layout")

Of course when you redirect you have to set the session variable like this:

>  isAjax <- isAjaxRequest
>  if isAjax then setSession Session.ajaxRequestKey "true" else return ()
>  redirect RedirectTemporary $ AuthR LoginR


More information about the web-devel mailing list