116 votes

Impossible de définir le type de contenu sur '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 je veux est de définir le type de contenu à partir de l'application/x-www-form-urlencoded d' 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 demande étrange (ce que je peux voir dans un violon)

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 est-ce? Qu'est-ce que les OPTIONS quand il faut y POSTER? Et où est mon type de contenu d'ensemble de l'application/json? Et les paramètres de la demande a disparu pour une raison quelconque.

Mise à JOUR 1

Sur le côté serveur, j'ai vraiment simple service RESTful.

[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 que je ne peux pas appeler cette méthode avec des paramètres.

Mise à JOUR 2

Désolé de ne pas répondre si longtemps.

J'ai ajouté ces en-têtes à ma réponse du serveur

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

Il n'a pas aidé, j'ai la Méthode non autorisée d'erreur du serveur.

Voici ce que ma dit fiddler

enter image description here

Alors, maintenant, je peux être sûr que mon serveur accepte POST, GET, les OPTIONS (si les en-têtes de réponse de travailler comme je attendre). Mais pourquoi "Méthode non autorisée"?

Dans WebView réponse du serveur (vous pouvez voir le Raw de réponse sur l'image ci-dessus) ressemble à ceci

enter image description here

103voto

Spike Points 632

Il semblerait que la suppression d' http:// à partir de l'url option permet de s'assurer de la correcte HTTP POST-tête est envoyé.

Je ne pense pas que vous avez besoin pour obtenir 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 la 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és: jQuery $.ajax(), $.post envoyer des "OPTIONS" comme REQUEST_METHOD dans Firefox

Edit: Après quelques recherches, j'ai trouvé les OPTIONS d'en-tête est utilisé pour savoir si la demande en provenance des domaine est autorisé. À l'aide de fiddler, j'ai ajouté ce qui suit pour les en-têtes de réponse à partir 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, puis envoyé à la bonne requête POST avec les données json. Il semblerait que le défaut form-urlencoded type de contenu est considéré comme sûr et donc ne subit pas de l'extra croix domaine des contrôles.

Il semble que vous aurez besoin d'ajouter, déjà mentionnés, les en-têtes de vos serveurs de réponse à la demande OPTIONS. Il convient évidemment de les configurer pour autoriser les demandes provenant de domaines spécifiques, plutôt que de tout.

J'ai utilisé jQuery pour tester cela.

$.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);
  }
});​

Références:

45voto

Amritpal Singh Points 1133

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;
                }
            }
        });
    }
 

2voto

Fanda Points 1162

J'ai trouvé la solution à ce problème ici . N'oubliez pas d'autoriser les options de verbe sur le gestionnaire de service de l'application IIS.

Fonctionne bien. Merci André Pedroso. :-)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X