J'ai un client jQuery qui fait une demande de publication Ajax à un contrôleur Spring. Côté serveur, aucune erreur n'a été enregistrée. Côté client, la demande est bloquée en attente très longtemps, en minutes, puis peut échouer avec ERR_SPDY_PROTOCOL_ERROR ou ERR_CONNECTION_CLOSED.
Ce problème est reproductible sur Chrome, mais pas sur Firefox. La version affectée vérifiée est 70.0.3538.77, il peut y en avoir d'autres également. En outre, le problème se produit sur un déploiement spécifique de l'application et non ailleurs, sur le développement ou la production.
Le client envoie des requêtes HTTPS 2 sur cet environnement. Dans l'environnement de développement, c'est HTTP 1.1. Sur le serveur, toutes les demandes sont enregistrées en 1.1.
Pour aucune raison apparente, les demandes ont commencé à être traitées, mais il s'agit d'un problème récurrent et nous aimerions le résoudre. Depuis que le problème a commencé à se produire, je ne peux pas le reproduire et vérifier si le problème est trop de connexions au serveur (plus de 6). J'utilise trois serveurs DNS, dont le dernier est le 8.8.8.8 de Google.
Je recherche un correctif de code ou une indication si cela peut être lié à la configuration du serveur. Je suis presque certain qu'il s'agit d'une combinaison de code client et de mise en réseau.
Ce que le problème n'est pas:
Antivirus ( erreur Chrome net :: ERR_INCOMPLETE_CHUNKED_ENCODING )
Relatif au service de prédiction ( requêtes ajax bloquées et en attente par JQuery dans Chrome ) - le commentaire sur le proxy et les connexions semble cependant plus pertinent.
Extension/plug-in de blocage des publicités ( Échec du chargement de la ressource sous Chrome )
Ce que j'ai essayé sans succès:
Ce qui ne répond pas à la question:
Côté client, j'ai essayé d'effacer les données du navigateur, de vider les sockets et la navigation privée/incognito.
La seule chose qui parfois, rarement, contourne l'erreur se passe en mode incognito et vider les sockets et vider le cache de chrome: // net-internals/# events
var formData = new FormData();
formData.append( /* ... */ );
//...
$.ajax({
type: "POST",
url: "/somepath/update",
cache: false,
data: formData,
contentType: false,
processData: false,
success: function(result) {
//...
},
fail: function(result) {
//....
},
error: function( jqXHR, textStatus, errorThrown ){
alert(textStatus + ":" + errorThrown);
}
});
Une demande distincte utilisant $ .post était en cours:
$.post("someotherpath/update", $("#someForm").serialize())
.done(function (data) {
//...
})
.fail(function (data) {
//...
})
.always(function () {
//...
});
Du côté serveur:
@RequestMapping(value="/somepath/update", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public @ResponseBody String update(ModelClass model) {
JSONObject result = new JSONObject();
//...
return result.toString();
}
S'il est pertinent, il existe les filtres suivants. Je crains de ne pas pouvoir en publier plus pour le moment:
@Configurable
public class Filter1 extends OpenEntityManagerInViewFilter implements Filter{
public void doFilterInternal(HttpServletRequest httpReq, HttpServletResponse httpResp, FilterChain chain)
throws ServletException, IOException {
//...
}
}
@Configurable
public class Filter2 extends OncePerRequestFilter implements Filter{
public void doFilterInternal(HttpServletRequest httpReq, HttpServletResponse httpResp, FilterChain chain)
throws ServletException, IOException {
//...
}
}
@Order(/* very small integer */)
public class Filter3 extends OncePerRequestFilter {
}
Le résultat attendu est que le code doit passer par le rappel de réussite. Au lieu de cela, la demande est bloquée en attente pendant quelques minutes, puis entre le rappel d'erreur.
$.post
Appelle $.ajax
Sous les couvertures par défaut, plusieurs des options.
$.post
Par défaut contentType
à "application/x-www-form-urlencoded; charset=UTF-8"
, Ce qui correspondrait à la charge utile des données de votre formulaire sérialisé.
Votre appel à $.ajax
Définit contentType
sur false
- ce qui peut amener le navigateur à envoyer une requête OPTIONS avant le vol au serveur, ce qui peut être à l'origine de la différence de comportement vous vivez.
Je suggère de lire les détails sur jQuery.ajax()
et les différents comportements basés sur options passées ici