web-dev-qa-db-ger.com

Der Inhaltstyp kann nicht in 'application/json' in jQuery.ajax festgelegt werden

Wenn ich diesen Code habe

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

in Fiddler kann ich folgenden Rohwunsch sehen

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

Aber ich versuche, den Inhaltstyp aus application/x-www-form-urlencoded in application/json zu setzen. Aber dieser Code

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

Erzeugt eine seltsame Anfrage (die ich in Fiddler sehen kann)

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

Warum das? Was ist OPTIONEN, wenn dort POST sein sollte? Und wo ist mein Inhaltstyp auf application/json eingestellt? Und die Anforderungsparameter sind aus irgendeinem Grund gegangen.

UPDATE 1

Auf Serverseite habe ich wirklich einfachen RESTful-Service.

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

Aber aus irgendeinem Grund kann ich diese Methode nicht mit Parametern aufrufen.

UPDATE 2

Entschuldigung, dass ich nicht so lange geantwortet habe. 

Ich habe diese Header zu meiner Serverantwort hinzugefügt

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

Es hat nicht geholfen, ich habe Methode nicht erlaubt Fehler vom Server.

Folgendes sagt mein Geiger

enter image description here

Jetzt kann ich sicher sein, dass mein Server POST, GET, OPTIONS akzeptiert (wenn Antwortheader wie erwartet funktionieren). Aber warum "Methode nicht erlaubt"?

In der WebView-Antwort vom Server (Sie können die Antwort von Raw im Bild oben sehen) sieht das so aus

enter image description here

83

Es scheint, dass durch das Entfernen von http:// aus der URL-Option sichergestellt wird, dass der richtige HTTP-Header POST gesendet wird.

Ich denke nicht, dass Sie den Namen des Hosts vollständig qualifizieren müssen, verwenden Sie einfach eine relative URL wie unten.

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

Ein Beispiel von mir, das funktioniert:

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

Möglicherweise verwandt: jQuery $ .ajax (), $ .post sendet "OPTIONS" als REQUEST_METHOD in Firefox

Edit: Nach einiger Recherche fand ich heraus, dass der OPTIONS-Header verwendet wird, um herauszufinden, ob die Anfrage aus der Ursprungsdomäne zulässig ist. Mit Fiddler fügte ich den Antwortheatern meines Servers Folgendes hinzu.

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

Sobald der Browser diese Antwort erhalten hat, sendet er die richtige POST - Anforderung mit json-Daten ab. Es scheint, dass der Standardinhaltstyp mit urlencodiertem Inhalt als sicher gilt und daher nicht den zusätzlichen domänenübergreifenden Prüfungen unterzogen wird.

Es scheint, dass Sie die zuvor erwähnten Header Ihrer Serverantwort auf die Anfrage OPTIONS hinzufügen müssen. Sie sollten sie natürlich so konfigurieren, dass Anfragen von bestimmten Domänen statt von allen zugelassen werden.

Ich habe die folgende jQuery verwendet, um dies zu testen.

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

Verweise:

75
Mike Wade

Ich kann dir zeigen, wie ich es benutzt habe 

  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;
                }
            }
        });
    }
31
Amritpal Singh

Alles, was Sie dafür tun müssen, ist folgendes hinzuzufügen:

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

als ein Feld für Ihre Post-Anfrage und es wird funktionieren.

9
Cody Jacques

Ich habe diese Bildschirme erkannt, ich verwende CodeFluentEntities und eine Lösung, die auch für mich funktioniert hat.

Ich verwende diese Konstruktion:

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

wie du sehen kannst, wenn ich benutze 

contentType: "",

oder

contentType: "text/plain", //chrome

Alles funktioniert gut.

Ich bin nicht zu 100% sicher, dass es alles ist, was Sie brauchen, denn ich habe auch die Header geändert. 

4
Alexey Avdeyev

Ich habe die Lösung für dieses Problem gefunden hier . Vergessen Sie nicht, das Verb OPTIONS im App-Service-Handler IIS zuzulassen. 

Funktioniert gut. Vielen Dank, André Pedroso. :-)

2
Fanda

Wenn Sie dies verwenden:

contentType: "application/json"

AJAX hat keine GET- oder POST -Parameter an den Server gesendet. Weiß nicht, warum.

Ich habe heute Stunden gebraucht, um es zu lernen.

Benutz einfach:

$.ajax(
  { url : 'http://blabla.com/wsGetReport.php',
    data : myFormData, type : 'POST', dataType : 'json', 
    // contentType: "application/json", 
    success : function(wsQuery) { }
  }
)

Ich hatte das gleiche Problem. Ich führe eine Java-Rest-App auf einem JBoss-Server aus. Aber ich denke, dass die Lösung auf einer .NET App von ASP ähnlich ist.

Firefox ruft Ihren Server/Rest-URL vorab auf, um zu prüfen, welche Optionen zulässig sind. Das ist die "OPTIONS" -Anforderung, auf die Ihr Server nicht entsprechend antwortet. Wenn dieser OPTIONS-Aufruf korrekt beantwortet wird, wird ein zweiter Aufruf durchgeführt, bei dem es sich um die eigentliche "POST" -Anforderung mit json-Inhalt handelt.

Dies geschieht nur bei einem domänenübergreifenden Anruf. In Ihrem Fall rufen Sie "http://localhost:16329/Hello" auf, anstatt einen URL-Pfad unter derselben Domäne "/ Hello" aufzurufen.

Wenn Sie einen domänenübergreifenden Anruf durchführen möchten, müssen Sie Ihre Rest-Service-Klasse um eine kommentierte Methode erweitern, die eine http-Anforderung "OPTIONS" unterstützt. Dies ist die entsprechende Java-Implementierung:

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

Ich denke, in .NET müssen Sie eine zusätzliche, mit Anmerkungen versehene Methode hinzufügen

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

wo die folgenden Header gesetzt sind

.header("Access-Control-Allow-Origin", "*")
        .header("Access-Control-Allow-Headers", "Content-Type")
        .header("Access-Control-Allow-Methods", "POST, OPTIONS")
1
Vincent

Ich habe die Lösung erhalten, die JSON-Daten per POST -Anforderung über Jquery Ajax zu senden. Ich habe den folgenden Code verwendet

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


        });
    });

Ich habe 'Content-Type': 'text/plain' im Header verwendet, um die rohen Json-Daten zu senden.
Denn wenn wir Content-Type: 'application/json' verwenden, werden die Anforderungsmethoden in OPTION konvertiert, aber mit Content-Type: 'test/plain' wird die Methode nicht konvertiert und verbleibt als POST . Hoffentlich hilft dies einigen.

0
Rahul Aparajit