Ne peut pas définir content-type à 'application / json' dans jQuery.Ajax

quand j'ai ce code

$.ajax({
    type: 'POST',
    //contentType: "application/json",
    url: 'http://localhost:16329/Hello',
    data: { name: 'norm' },
    dataType: 'json'
});

dans un violon, je peux voir la suite de la requête brute

POST http://localhost:16329/Hello HTTP/1.1
Host: localhost:16329
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:14693/WebSite1/index.html
Content-Length: 9
Origin: http://localhost:14693
Pragma: no-cache
Cache-Control: no-cache

name=norm

mais ce que j'essaie est de mettre le type de contenu de application/x-www-form-urlencoded à application/json . Mais ce code

$.ajax({
    type: "POST",
    contentType: "application/json",
    url: 'http://localhost:16329/Hello',
    data: { name: 'norm' },
    dataType: "json"
});

génère une requête étrange (que je peux voir dans Fiddler)

OPTIONS http://localhost:16329/Hello HTTP/1.1
Host: localhost:16329
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Origin: http://localhost:14693
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Pragma: no-cache
Cache-Control: no-cache

pourquoi? Qu'est-ce que OPTIONS quand il faut y POSTER? Et où est mon type de contenu défini à application / json? Et les paramètres de requête ont disparu pour une raison ou une autre.

UPDATE 1

côté serveur, j'ai un service très simple et reposant.

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class RestfulService : IRestfulService
{
    [WebInvoke(
        Method = "POST",
        UriTemplate = "Hello",
        ResponseFormat = WebMessageFormat.Json)]
    public string HelloWorld(string name)
    {
        return "hello, " + name;
    }
}

mais pour une raison quelconque Je ne peux pas appeler cette méthode avec des paramètres.

UPDATE 2

désolé de ne pas répondre à si longtemps.

j'ai ajouté ces en-têtes à la réponse de mon serveur

 Access-Control-Allow-Origin: *
 Access-Control-Allow-Headers: Content-Type
 Access-Control-Allow-Methods: POST, GET, OPTIONS

cela n'a pas aidé, j'ai méthode non autorisée erreur du serveur.

voici ce que dit Mon violon

enter image description here

donc, maintenant je peux être sûr que mon serveur accepte POST, GET, OPTIONS (si les en-têtes de réponse fonctionnent comme je l'attends). Mais pourquoi "méthode interdite"?

dans la réponse de WebView du serveur (vous pouvez voir Raw réponse sur la photo ci-dessus) ressemble à ceci

enter image description here

83
demandé sur Vitalii Korsakov 2012-03-18 03:39:33

8 réponses

il semblerait que la suppression de http:// de l'option url assure l'envoi du bon en-tête HTTP POST.

Je ne pense pas que vous devez pleinement qualifier le nom de l'hôte, il suffit d'utiliser une URL relative comme ci-dessous.

   $.ajax({
      type: "POST",
      contentType: "application/json",
      url: '/Hello',
      data: { name: 'norm' },
      dataType: "json"
   });

un exemple de mine qui fonctionne:

        $.ajax({
            type: "POST",
            url: siteRoot + "api/SpaceGame/AddPlayer",
            async: false,
            data: JSON.stringify({ Name: playersShip.name, Credits: playersShip.credits }),
            contentType: "application/json",
            complete: function (data) {
            console.log(data);
            wait = false;
        }
    });

peut-être liée: jQuery $.Ajax.$ ,)(post sending "OPTIONS" as REQUEST_METHOD in Firefox

Edit: Après quelques recherches, j'ai découvert que L'en-tête OPTIONS est utilisé pour savoir si la requête du domaine source est autorisée. En utilisant fiddler, j'ai ajouté ce qui suit aux en-têtes de réponse de mon serveur.

 Access-Control-Allow-Origin: *
 Access-Control-Allow-Headers: Content-Type
 Access-Control-Allow-Methods: POST, GET, OPTIONS

une fois que le navigateur a reçu cette réponse, il a ensuite envoyé la demande de poste correcte avec les données json. Il semblerait que le type de contenu form-urlencoded par défaut soit considéré comme sûr et ne subisse donc pas les vérifications croisées supplémentaires du domaine.

il semble que vous aurez besoin d'ajouter les en-têtes mentionnés précédemment à la réponse de vos serveurs à la requête D'OPTIONS. Vous devez bien sûr les configurer pour autoriser les requêtes de domaines spécifiques plutôt que toutes.

j'ai utilisé le jQuery suivant pour tester ceci.

$.ajax({
   type: "POST",
   url: "http://myDomain.com/path/AddPlayer",
   data: JSON.stringify({
      Name: "Test",
       Credits: 0
   }),
   //contentType: "application/json",
   dataType: 'json',
   complete: function(data) {
       $("content").html(data);
  }
});​

, les Références:

74
répondu Spike 2017-05-23 12:02:53

je peux vous montrer comment je l'ai utilisé""

  function GetDenierValue() {
        var denierid = $("#productDenierid").val() == '' ? 0 : $("#productDenierid").val();
        var param = { 'productDenierid': denierid };
        $.ajax({
            url: "/Admin/ProductComposition/GetDenierValue",
            dataType: "json",
            contentType: "application/json;charset=utf-8",
            type: "POST",
            data: JSON.stringify(param),
            success: function (msg) {
                if (msg != null) {
                    return msg.URL;
                }
            }
        });
    }
27
répondu Amritpal Singh 2017-05-09 16:21:53

Donc tout ce que vous devez faire pour que cela fonctionne, c'est d'ajouter:

headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
}

comme un champ à votre demande de poste et il fonctionnera.

8
répondu Cody Jacques 2016-01-19 19:55:26

j'ai reconnu ces écrans, j'utilise CodeFluentEntities, et j'ai une solution qui a fonctionné pour moi aussi.

j'utilise cette construction:

$.ajax({
   url: path,
   type: "POST",
   contentType: "text/plain",
   data: {"some":"some"}
}

comme vous pouvez le voir, si j'utilise

contentType: "",

ou

contentType: "text/plain", //chrome

Tout fonctionne très bien.

Je ne suis pas sûr à 100% que ce soit tout ce dont vous avez besoin, parce que j'ai aussi changé les en-têtes.

4
répondu Alexey Avdeyev 2015-02-27 07:33:42

j'ai trouvé la solution pour ce problème ici . N'oubliez pas d'autoriser les OPTIONS de verbe sur IIS app service handler.

fonctionne très bien. Merci André Pedroso. :- )

2
répondu Fanda 2013-09-11 11:34:25

j'ai eu le même problème. J'exécute une application Java rest sur un serveur jboss. Mais je pense que la solution est similaire sur un ASP.NET webapp.

Firefox effectue un pré-appel à votre url serveur / rest pour vérifier quelles options sont autorisées. C'est la requête" OPTIONS " à laquelle votre serveur ne répond pas en conséquence. Si cet appel D'OPTIONS est répondu correctement, un second appel est effectué qui est la requête "POST" réelle avec le contenu json.

ce seul se produit lors de l'exécution d'un inter-domaine d'appel. Dans votre cas, appeler ' http://localhost:16329/Hello 'au lieu d'appeler un chemin d'url sous le même domaine '/ Hello '

si vous avez l'intention de faire un appel de domaine croisé, vous devez améliorer votre classe de service de repos avec une méthode annotée la prise en charge d'une demande http" OPTIONS". C'est l'implémentation java correspondante:

@Path("/rest")
public class RestfulService {

    @POST
    @Path("/Hello")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.TEXT_PLAIN)
    public string HelloWorld(string name)
    {
        return "hello, " + name;
    }

//THIS NEEDS TO BE ADDED ADDITIONALLY IF MAKING CROSS-DOMAIN CALLS

    @OPTIONS
    @Path("/Hello")
    @Produces(MediaType.TEXT_PLAIN+ ";charset=utf-8")
    public Response checkOptions(){
        return Response.status(200)
        .header("Access-Control-Allow-Origin", "*")
        .header("Access-Control-Allow-Headers", "Content-Type")
        .header("Access-Control-Allow-Methods", "POST, OPTIONS") //CAN BE ENHANCED WITH OTHER HTTP CALL METHODS 
        .build();
    }
}

donc je suppose que dans .NET vous devez ajouter une méthode supplémentaire annotée avec

[WebInvoke(
        Method = "OPTIONS",
        UriTemplate = "Hello",
        ResponseFormat = WebMessageFormat.)]

où les en-têtes suivants sont placés

.header("Access-Control-Allow-Origin", "*")
        .header("Access-Control-Allow-Headers", "Content-Type")
        .header("Access-Control-Allow-Methods", "POST, OPTIONS")
1
répondu Vincent 2014-12-09 16:07:42

si vous utilisez ceci:

contentType: "application/json"

AJAX n'envoie pas GET ou POST params au serveur.... je ne sais pas pourquoi.

il m'a fallu des heures pour l'apprendre aujourd'hui.

Il Suffit D'Utiliser:

$.ajax(
  { url : 'http://blabla.com/wsGetReport.php',
    data : myFormData, type : 'POST', dataType : 'json', 
    // contentType: "application/json", 
    success : function(wsQuery) { }
  }
)
1
répondu Luis Arturo Erique Guajala 2017-03-04 01:23:54

j'ai eu la solution pour envoyer les données JSON par la demande de poste par l'intermédiaire de jQuery ajax. J'ai utilisé ci-dessous le code

    var data = new Object();
    data.p_clientId = 4;
    data =  JSON.stringify(data);

    $.ajax({
      method: "POST",
      url: "http://192.168.1.141:8090/api/Client_Add",
      data: data,
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'text/plain'
    }
    })
      .done(function( msg ) {
        alert( "Data Saved: " + msg );
      });


        });
    });

j'ai utilisé 'Content-Type': 'text/plain' dans l'en-tête pour envoyer les données brutes json.

Parce que si nous utilisons Content-Type: 'application/json' les méthodes de requête converties en OPTION, mais en utilisant Content-Type: 'test/plain' la méthode ne se convertit pas et reste comme POST. J'espère que cela aidera certains.

0
répondu Rahul Aparajit 2018-03-28 09:06:03