J'ai une fonction côté serveur qui nécessite une connexion. Si l'utilisateur est connecté, la fonction retournera 1 en cas de succès. Sinon, la fonction retournera la page de connexion.
Je veux appeler la fonction en utilisant Ajax et jQuery. Ce que je fais est de soumettre la demande avec un lien ordinaire, avec une fonction de clic appliquée dessus. Si l'utilisateur n'est pas connecté ou si la fonction échoue, je souhaite que l'appel Ajax renvoie true, pour que le déclencheur href se déclenche.
Cependant, lorsque j'utilise le code suivant, la fonction se ferme avant que l'appel Ajax soit terminé.
Comment puis-je rediriger gracieusement l'utilisateur vers la page de connexion?
$(".my_link").click(
function(){
$.ajax({
url: $(this).attr('href'),
type: 'GET',
cache: false,
timeout: 30000,
error: function(){
return true;
},
success: function(msg){
if (parseFloat(msg)){
return false;
} else {
return true;
}
}
});
});
Si vous ne souhaitez pas que la fonction $.ajax()
revienne immédiatement, définissez l'option async
sur false
:
$(".my_link").click(
function(){
$.ajax({
url: $(this).attr('href'),
type: 'GET',
async: false,
cache: false,
timeout: 30000,
error: function(){
return true;
},
success: function(msg){
if (parseFloat(msg)){
return false;
} else {
return true;
}
}
});
});
Mais je ferais remarquer que cela irait à l’encontre du principe d’AJAX. Vous devez également gérer la réponse dans les fonctions error
et success
. Ces fonctions ne seront appelées que lorsque la réponse sera reçue du serveur.
Je n'utilise pas $.ajax
mais les fonctions $.post
et $.get
, donc si j'ai besoin d'attendre la réponse, j'utilise ceci:
$.ajaxSetup({async: false});
$.get("...");
L'objet XMLHttpRequest sous-jacent (utilisé par jQuery pour effectuer la demande) prend en charge la propriété asynchrone. Réglez-le sur false. Comme
async: false
Au lieu de définir async sur false, ce qui est généralement une mauvaise conception, vous pouvez envisager de bloquer l'interface utilisateur pendant que l'opération est en attente.
Ceci peut être parfaitement réalisé avec les promesses jQuery suivantes:
// same as $.ajax but settings can have a maskUI property
// if settings.maskUI==true, the UI will be blocked while ajax in progress
// if settings.maskUI is other than true, it's value will be used as the color value while bloking (i.e settings.maskUI='rgba(176,176,176,0.7)'
// in addition an hourglass is displayed while ajax in progress
function ajaxMaskUI(settings) {
function maskPageOn(color) { // color can be ie. 'rgba(176,176,176,0.7)' or 'transparent'
var div = $('#maskPageDiv');
if (div.length === 0) {
$(document.body).append('<div id="maskPageDiv" style="position:fixed;width:100%;height:100%;left:0;top:0;display:none"></div>'); // create it
div = $('#maskPageDiv');
}
if (div.length !== 0) {
div[0].style.zIndex = 2147483647;
div[0].style.backgroundColor=color;
div[0].style.display = 'inline';
}
}
function maskPageOff() {
var div = $('#maskPageDiv');
if (div.length !== 0) {
div[0].style.display = 'none';
div[0].style.zIndex = 'auto';
}
}
function hourglassOn() {
if ($('style:contains("html.hourGlass")').length < 1) $('<style>').text('html.hourGlass, html.hourGlass * { cursor: wait !important; }').appendTo('head');
$('html').addClass('hourGlass');
}
function hourglassOff() {
$('html').removeClass('hourGlass');
}
if (settings.maskUI===true) settings.maskUI='transparent';
if (!!settings.maskUI) {
maskPageOn(settings.maskUI);
hourglassOn();
}
var dfd = new $.Deferred();
$.ajax(settings)
.fail(function(jqXHR, textStatus, errorThrown) {
if (!!settings.maskUI) {
maskPageOff();
hourglassOff();
}
dfd.reject(jqXHR, textStatus, errorThrown);
}).done(function(data, textStatus, jqXHR) {
if (!!settings.maskUI) {
maskPageOff();
hourglassOff();
}
dfd.resolve(data, textStatus, jqXHR);
});
return dfd.promise();
}
avec cela, vous pouvez maintenant faire:
ajaxMaskUI({
url: url,
maskUI: true // or try for example 'rgba(176,176,176,0.7)'
}).fail(function (jqXHR, textStatus, errorThrown) {
console.log('error ' + textStatus);
}).done(function (data, textStatus, jqXHR) {
console.log('success ' + JSON.stringify(data));
});
Et l'interface utilisateur bloquera jusqu'au retour de la commande ajax
voir jsfiddle
Je pense que les choses seraient plus faciles si vous codiez votre fonction success
pour charger la page appropriée au lieu de renvoyer true
ou false
.
Par exemple, au lieu de retourner true
, vous pourriez faire:
window.location="appropriate page";
Ainsi, lorsque la fonction de succès est appelée, la page est redirigée.