How to redirect to the last visited page in Grails

2020-05-17 04:36发布

I am a newbie in Grails and I am struggling with many simple issues.

For instance, I haven't managed to find a proper way to go back to the last visited page when I login/logout from a template view that is displayed on the top layout of the page.

My last attempt at solving this problem was to save the ${params.controller} and ${params.action} in the parameters sent to the logout action and redirect thereafter. Well...even this failed. Here is the gsp snippet:

<g:link controller="user" action="logout" params="[currentController: ${params.controller}, currentAction: ${params.action}]">Logout</g:link>

This last code line throws the following exception:

ERROR errors.GrailsExceptionResolver  - Error evaluating expression [[currentController: ${params.controller}, currentAction: ${params.action}]]

So my questions are:

1 - How can I reload the last visited page after a login/logout action ?

2 - Why do I have an exception from my code above?

Thank You

EDIT : Concerning question #2, it seems that the following code is working:

<g:link controller="user" action="logout" params="[currentController: params.controller, currentAction: params.action]">Logout</g:link>

But I don't really understand the reason...

EDIT2 : I have also found out a solution for redirecting to the last visited page:

redirect(url: request.header('referer'))

But unfortunately when doing this after login, the contents rendered in my page are duplicated. Any idea or any other safe solution?

4条回答
狗以群分
2楼-- · 2020-05-17 05:18

The easiest way to redirect to the last page, is to use the URI directly:

<g:link controller="user" action="logout" params="[targetUri: (request.forwardURI - request.contextPath)]">Logout</g:link>

(request.forwardURI is the complete URL as displayed in the browser, while request.contextPath is the URL part representing the app context, eg. "http://localhost:8080/yourApp" - thus, the result of removing the context path from the forward URI is the app-relative URI, eg. "/mycontroller/myaction")

In your logout action simply redirect to this URI:

def targetUri = params.targetUri ?: "/"
redirect(uri: targetUri)

AFAIK, using the referrer is not entirely safe, because this relies on the user agent (browser) to append the referrer HTTP header (which may have been disabled).

As to your 2nd question: Grails automatically interprets list or map attribute values in GSPs as Groovy expressions. So, this

<g:link controller="user" action="logout" params="[currentController: params.controller, currentAction: params.action]">Logout</g:link>

is equivalent to

<g:link controller="user" action="logout" params="${[currentController: params.controller, currentAction: params.action]}">Logout</g:link>

and wrapping parts of this expression again in ${...} seems to confuse the GSP compiler.

Hope this helps.

查看更多
虎瘦雄心在
3楼-- · 2020-05-17 05:19

Another alternative is to build the url with createLink using the current: actionName, controllerName and params.

<g:link controller="user" action="logout" params="[targetUri: createLink(controller: controllerName, action:actionName, params:params, absolute:true)]">Logout</g:link>

This will create an absolute url, because of the absolute:true.

查看更多
Summer. ? 凉城
4楼-- · 2020-05-17 05:25

In GSP view file you can use as such.

<g:link url="${request.getHeader('referer')}"> Back </g:link>
查看更多
爷、活的狠高调
5楼-- · 2020-05-17 05:29

I'm using this controller-side:

    redirect(uri: request.getHeader('referer') )
查看更多
登录 后发表回答