我使用$.post()使用Ajax调用servlet,然后使用生成的HTML片段替换用户当前页面中的div元素。但是,如果会话超时,服务器将发送重定向指令,将用户发送到登录页面。在本例中,jQuery用登录页面的内容替换div元素,迫使用户的眼睛看到一个罕见的场景。
如何使用jQuery1.2.6管理Ajax调用的重定向指令?
我使用$.post()使用Ajax调用servlet,然后使用生成的HTML片段替换用户当前页面中的div元素。但是,如果会话超时,服务器将发送重定向指令,将用户发送到登录页面。在本例中,jQuery用登录页面的内容替换div元素,迫使用户的眼睛看到一个罕见的场景。
如何使用jQuery1.2.6管理Ajax调用的重定向指令?
当前回答
后端弹簧@ExceptionHandler。
400和业务相关异常的错误字符串(将在弹出窗口中显示)302和用于浏览器请求的应用程序异常的错误/登录页面的位置标头(由浏览器自动重定向)500/400和错误/登录页面的位置头,用于通过ajax回调重定向ajax请求
通过用户会话将异常详细信息传递到错误页
@Order(HIGHEST_PRECEDENCE)
public class ExceptionHandlerAdvise {
private static Logger logger = LoggerFactory.getLogger(ExceptionHandlerAdvise.class);
@Autowired
private UserInfo userInfo;
@ExceptionHandler(value = Exception.class)
protected ResponseEntity<Object> handleException(Exception ex, WebRequest request) {
HttpHeaders headers = new HttpHeaders();
if (isBusinessException(ex)) {
logger.warn(getRequestURL(request), ex);
return new ResponseEntity<>(getUserFriendlyErrorMessage(ex), headers, BAD_REQUEST);
} else {
logger.error(getRequestURL(request), ex);
userInfo.setLastError(ex);
headers.add("Location", "/euc-portal/fault");
return new ResponseEntity<>(null, headers, isAjaxRequest(request) ? INTERNAL_SERVER_ERROR : FOUND);
}
}
}
private boolean isAjaxRequest(WebRequest request) {
return request.getHeader("x-requested-with") != null;
}
private String getRequestURL(WebRequest request) {
if (request instanceof ServletWebRequest) {
HttpServletRequest servletRequest = ((ServletWebRequest) request).getRequest();
StringBuilder uri = new StringBuilder(servletRequest.getRequestURI());
if (servletRequest.getQueryString() != null) {
uri.append("?");
uri.append(servletRequest.getQueryString());
}
return uri.toString();
}
return request.getContextPath();
}
登录手柄接口
@Service
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Autowired
private UserInfo userInfo;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (userInfo.getPrincipal() == null && !(request.getRequestURI().contains(LOGIN_URL) || request.getRequestURI().contains(FAULT_URL) || request.getRequestURI().startsWith("/app/css"))) {
response.addHeader("Location", LOGIN_URL);
response.setStatus(isAjaxRequest(request) ? BAD_REQUEST.value() : FOUND.value());
return false;
}
return true;
}
}
客户端代码
$.post('/app/request', params).done(function(response) {
...
}).fail(function(response) {
if (response.getResponseHeader('Location')) {
window.top.location.href = response.getResponseHeader('Location');
return;
}
alert(response);
});
其他回答
如果您还想传递值,那么还可以设置会话变量和访问如:在jsp中,您可以编写
<% HttpSession ses = request.getSession(true);
String temp=request.getAttribute("what_you_defined"); %>
然后,您可以将这个temp值存储在javascript变量中,并四处游玩
<script>
function showValues() {
var str = $("form").serialize();
$.post('loginUser.html',
str,
function(responseText, responseStatus, responseXML){
if(responseStatus=="success"){
window.location= "adminIndex.html";
}
});
}
</script>
使用低级$.ajax()调用:
$.ajax({
url: "/yourservlet",
data: { },
complete: function(xmlHttp) {
// xmlHttp is a XMLHttpRquest object
alert(xmlHttp.status);
}
});
尝试此操作进行重定向:
if (xmlHttp.code != 200) {
top.location.href = '/some/other/page';
}
我这样解决了这个问题:
添加一个中间件来处理响应,如果是对ajax请求的重定向,则使用重定向url将响应更改为正常响应。
class AjaxRedirect(object):
def process_response(self, request, response):
if request.is_ajax():
if type(response) == HttpResponseRedirect:
r = HttpResponse(json.dumps({'redirect': response['Location']}))
return r
return response
然后在ajaxComplete中,如果响应包含重定向,则它必须是重定向,因此请更改浏览器的位置。
$('body').ajaxComplete(function (e, xhr, settings) {
if (xhr.status == 200) {
var redirect = null;
try {
redirect = $.parseJSON(xhr.responseText).redirect;
if (redirect) {
window.location.href = redirect.replace(/\?.*$/, "?next=" + window.location.pathname);
}
} catch (e) {
return;
}
}
}
使用statusCode选项,如下所示,重定向通常是301、302状态代码。
$.ajax({
type: <HTTP_METHOD>,
url: {server.url},
data: {someData: true},
statusCode: {
301: function(responseObject, textStatus, errorThrown) {
//yor code goes here
},
302: function(responseObject, textStatus, errorThrown) {
//yor code goes here
}
}
})
.done(function(data){
alert(data);
})
.fail(function(jqXHR, textStatus){
alert('Something went wrong: ' + textStatus);
})
.always(function(jqXHR, textStatus) {
alert('Ajax request was finished')
});