2
votes

Problème CORS lors de la tentative de publication de JQuery avec des données json, mais pas avec du texte brut ou x-www-form-urlencoded

Problème, j'obtiens une réponse d'erreur CORS lorsque j'effectue une publication jQuery avec les données json de l'application. Mais je n'obtiens pas cette erreur avec les articles jQuery avec des données en clair / texte ou x-www-urlencoded-form.

Problème / Détails:

J'ai deux applications en cours d'exécution sur ma VM Ubuntu, une application React exécutée sur http: // localhost: 3000 et un service Web Java fonctionnant à partir d'un serveur Payara à partir de mon IDE Netbeans 10 à cette URL http: // cduran-virtualbox: 8080 / TestMavenWebApplication / firstservicecall . J'essaie de tester différentes publications jQuery avec différents types de contenu de l'application React au service Web.

Pour éviter d'obtenir un message d'erreur CORS, j'ai ajouté ceci au serveur Web java objet HttpServletRequest response.addHeader ("Access-Control-Allow-Origin", "http: // localhost: 3000");

Cependant, j'obtiens cette erreur lorsque j'écris une publication jQuery avec Json data:

public class FirstServlet extends HttpServlet {
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {

        String contentType = request.getHeader("content-type");
        response.addHeader("Access-Control-Allow-Origin", "http://localhost:3000");

        if (contentType.equals("text/plain")) {
            InputStream is = request.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String line = "";
            while((line = br.readLine()) != null) {
                System.out.println("Plain/Text data received: " + line);
            }
            response.getWriter().print("Hello back from Servlet - content type received plain text");
        } else if (contentType.equals("application/x-www-form-urlencoded; charset=utf-8")) {
            String msgReceived = request.getParameter("var1");
            System.out.println("Message Received: " + msgReceived);            
            response.getWriter().print("Hello back from Servlet - content type received x-www-form-urlencoded");
        } else if (contentType.toLowerCase().contains("json")) {
           JSONObject json = new JSONObject(request.getParameterMap());
           System.out.println("json data received: " + json.toString());
                       response.getWriter().print("Hello back from Servlet - content type received application/json");
        } else {
            response.getWriter().print("Hello back from Servlet - content type undefined");
        }
    }    
}

Mais j'ai deux autres méthodes de test qui font jQuery Posts (une où le content-type est text / plain et l'autre est application / x-www-form-urlencoded qui n'a pas ce problème, c'est-à-dire que je peux envoyer avec succès un message jQuery Post au service Web et obtenir une réponse.

Voici le code du jQuery Post avec les données json où J'ai le problème de réponse CORS :

  var myObject = {
      var1: 'Hello from CommunicationForm'  
   };
   var urlToPost = 'http://cduran-VirtualBox:8080/TestMavenWebApplication/firstservicecall';

   $.ajax({
       type: "POST",
       //dataType: "text",
       contentType: 'application/x-www-form-urlencoded; charset=utf-8',
       url: urlToPost,
       data: myObject,
       success: function(response) {
           console.log("application/x-www-form-urlencoded response: " + response);
       }
   });

Voici le jQuery publier avec du texte brut qui fonctionne (c'est-à-dire pas de réponse CORS, je peux voir le code du service Web atteint, et je peux voir la réponse en retour à cette application React qui a lancé le post jQuery):

var urlToPost = 'http://cduran-VirtualBox:8080/TestMavenWebApplication/firstservicecall';

   $.ajax({
       type: "POST",
       //dataType: "text",
       contentType: 'text/plain',
       url: urlToPost,
       data: "Hello from CommunicationForm (plain text)",
       success: function(response) {
         console.log("plain text response: " + response);
       }
   });   

Voici mon post jQuery avec x-www-urlencoded-form qui fonctionne également:

  var urlToPost = 'http://cduran-VirtualBox:8080/TestMavenWebApplication/firstservicecall';

  $.ajax({
     type: "POST",
     dataType: "json",
     contentType: 'application/json; charset=utf-8',
     //crossDomain: true,
     url: urlToPost,
     async:true,
     data: JSON.stringify({ Object: 'CD', Quantity: '4' }),
     success: function(response) {
        console.log("json response: " + response);
    },
    failure: function(errMsg) {
        alert(errMsg);
    }
 }); 

Comme preuve supplémentaire, voici une capture d'écran de mon application React, vous pouvez ignorer le champ de texte de saisie car il ne fait rien. Mais j'ai 3 boutons de soumission d'entrée. Comme on peut le déduire des noms de bouton, l'un fait le post jQuery ci-dessus avec le type de contenu x-www-urlencoded-form, l'autre fait text / plain, et l'autre json.

 entrez la description de l'image here

Après avoir cliqué sur le bouton x-www .., cette déclaration de journal (comme indiqué dans la capture d'écran) est renvoyée par le service Web (indiquant que cela fonctionne bien). p >

réponse application / x-www-form-urlencoded: Bonjour de retour de Servlet - type de contenu reçu x-www-form-urlencoded

Après avoir cliqué sur le bouton en clair, cette déclaration de journal est affichée sur la capture d'écran, ce qui prouve à nouveau que le jQuery Post fonctionne correctement:

Réponse en texte brut: Bonjour de retour du servlet - type de contenu reçu texte brut

Les deux derniers messages du journal de la console sont la réponse d'erreur CORS après avoir cliqué sur le bouton Submit_json.

EDIT / UPDATE 2:

Notes supplémentaires - En utilisant l'application Post Man, je peux envoyer le message HTTP avec application / json comme type de contenu à mon application de service Web Java et j'ai vu la réponse.

J'ai créé une application Java Maven standard (pas Web app) et je peux également envoyer un message HTTP avec application / json comme type de contenu à mon application de service Web Java, et je peux voir la réponse bien dedans.

Quand j'ai soumis le jQuery POST avec l'application / json de mon application Web REACT J'ai vu sur la page réseau des outils de développement sur le navigateur Web que le POST est envoyé en OPTION (cela s'est produit dans les navigateurs Firefox et Chrome).

Un commentaire dans ce lien https://github.com/angular/angular/issues/22492 mentionne pour envoyer des requêtes simples et répertorie les types de contenu qui n'incluent pas application/json.

Cela rend les choses plus confuses.

EDIT / UPDATE 1:

Voici mon code de serveur principal. Rien de très spécial, il vérifie simplement le champ d'en-tête de type de contenu, puis analyse l'objet et renvoie une réponse différente à l'application React.

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://cduran-virtualbox:8080/TestMavenWebApplication/firstservicecall. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).


3 commentaires

Quel est le code d'état HTTP de la réponse lorsque vous recevez ces messages d'erreur? Utilisez le volet Réseau des outils de développement du navigateur pour vérifier. En outre, la capture d'écran de la console dans la question montre deux messages Erreur d'analyse XML: erreur de syntaxe enregistrés dans la console. Pourquoi?


Encore plus intéressant, en utilisant l'application PostMan, je peux envoyer une publication Http avec le Content-Type défini sur application / json; charset = utf-8 à mon URL de service Web, et il obtient une réponse très bien.


Je viens de remarquer que le code d'état HTTP auquel vous avez fait référence a été trouvé dans le volet Réseau que vous avez également mentionné. URL de requête: http: // cduran-virtualbox: 8080 / TestMavenWebApplication / firsts‌ ervicecall Méthode de requête: OPTIONS Code d'état: 200 OK Adresse distante: 127.0.1.1:8080 Politique de référence: no-referrer-when-downgrade


3 Réponses :


0
votes

CORS dépend totalement de la valeur de l'en-tête Access-Control-Allow-Origin dans la réponse et il semble que la réponse à la requête avec le type de contenu json ne reçoive pas cet en-tête.

Je pense que la requête avec le type de contenu JSON peut échouer côté serveur et que l'en-tête "Access-Control-Allow-Origin" n'est défini que pour les requêtes réussies.

Avez-vous vérifié en mettant un point de débogage sur response.addHeader ("Access-Control-Allow-Origin", "http: // localhost: 3000"); s'il est atteint pour votre demande de type de contenu JSON?

Pourriez-vous s'il vous plaît partager le code du serveur où cet en-tête est défini?

Je suis désolé de poser mes questions dans la section de réponse au lieu de commenter car je ne peux pas commenter en ce moment.

MODIFIER: Code Jquery mis à jour pour la requête POST de type de contenu application / json. Veuillez partager le format brut de la demande qui peut être vu sous l'onglet Réseau au cas où cela ne fonctionnerait pas. Comme la requête n'est pas au bon format, elle ne touche pas l'implémentation côté serveur et c'est pourquoi l'en-tête n'est pas défini dans la réponse.

var urlToPost = 'http://cduran-VirtualBox:8080/TestMavenWebApplication/firstservicecall';

  $.ajax({
     url: urlToPost,
     type: "POST",
     contentType: 'application/json',
     data: JSON.stringify({ “Object”: “CD”, “Quantity”: “4” }),
     success: function(response) {
        console.log("json response: " + response);
    },
    failure: function(errMsg) {
        alert(errMsg);
    }
 }); 


3 commentaires

Merci d'avoir pris le temps de commenter, j'ai mis à jour mon message d'origine pour afficher le code java principal. Je dois admettre que même avec un point d'arrêt dans le code java back-end, il n'est jamais touché lorsque je fais le jQuery Post de Submit_json.


@CDVAProgrammer D'après ces informations supplémentaires, il semble que la requête générée par le code jquery pour le type de contenu application / json est incorrecte. J'ai ajouté un code jQuery mis à jour pour le même. Après avoir utilisé ce code mis à jour, pourriez-vous s'il vous plaît la demande dans l'onglet réseau et partager le format brut de la demande si cela ne fonctionne pas?


Malheureusement, je reçois toujours la réponse d'erreur CORS sur le front-end. J'étudie toujours pour voir s'il me manque un autre champ d'en-tête.



5
votes

Les seules valeurs de l'en-tête Content-Type dans une requête simple sont les suivantes:

  • application / x-www-form-urlencoded
  • multipart / form-data
  • texte / brut

Essayez de remplacer "application / json" par un autre type de contenu, sinon le navigateur effectuera une demande de contrôle en amont.

Reportez-vous à la documentation CORS: https: //developer.mozilla. org / en-US / docs / Web / HTTP / CORS


1 commentaires

Je viens de voir cela du développeur . mozilla.org/en-US/docs/Web/HTTP/Headers/... section des directives de lien. Merci pour la contribution.



2
votes

Je pense que j'ai peut-être trouvé le problème, renforçant encore ce qu'Indrajit Bhaskaran a répondu ci-dessus.

Par ce lien https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers#Directives

Notez que certains en-têtes sont toujours autorisés: Accept, Accept-Language, Content-Language, Content-Type (mais uniquement avec un type MIME de son valeur analysée (ignorant les paramètres) de l'un ou l'autre application / x-www-form-urlencoded, multipart / form-data, ou text / plain ). Ceux-ci sont appelés les en-têtes simples, et vous n'avez pas besoin pour les spécifier explicitement.

La clé à retenir de ce qui précède est que seuls ces 3 types de contenu sont autorisés à partir d'un site Web vers un backend pour une demande.


0 commentaires