Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot set content-type to 'application/json' in jQuery.ajax

When I have this code

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

in Fiddler I can see following raw request

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 

But what I'm trying is to set content-type from application/x-www-form-urlencoded to application/json. But this code

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

Generates strange request (which I can see in 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 

Why is that? What is OPTIONS when it should be POST there? And where is my content-type set to application/json? And request parameters has gone for some reason.

UPDATE 1

On server side I have really simple 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;     } } 

But for some reason I can't call this method with parameters.

UPDATE 2

Sorry for not answering so long.

I've added these headers to my server response

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

It didn't help, I have Method not allowed error from server.

Here is what my fiddler says

enter image description here

So, now I can be sure that my server accepts POST, GET, OPTIONS (if response headers work like I expect). But why "Method not allowed"?

In WebView response from server (you can see Raw response on picture above) looks like this

enter image description here

like image 767
Vitalii Korsakov Avatar asked Mar 17 '12 23:03

Vitalii Korsakov


People also ask

How to set content type application json in ajax call?

Try this: $. ajax({ url:url, type:"POST", data:data, contentType:"application/json; charset=utf-8", dataType:"json", success: function(){ ... } })

How to specify content type in jQuery ajax call?

Default is "application/x-www-form-urlencoded; charset=UTF-8", which is fine for most cases. If you explicitly pass in a content-type to $.ajax() , then it is always sent to the server (even if no data is sent). As of jQuery 1.6 you can pass false to tell jQuery to not set any content type header.

Why do we use content type in Ajax?

contentType is the type of data you're sending, so application/json; charset=utf-8 is a common one, as is application/x-www-form-urlencoded; charset=UTF-8 , which is the default. dataType is what you're expecting back from the server: json , html , text , etc.

What mime type should a server set when sending a json response to an Ajax request?

text/plain was typically used for JSON, but according to IANA, the official MIME type for JSON is application/json .


2 Answers

It would seem that removing http:// from the url option ensures the the correct HTTP POST header is sent.

I dont think you need to fully qualify the name of the host, just use a relative URL as below.

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

An example of mine that works:

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

Possibly related: jQuery $.ajax(), $.post sending "OPTIONS" as REQUEST_METHOD in Firefox

Edit: After some more research I found out the OPTIONS header is used to find out if the request from the originating domain is allowed. Using fiddler, I added the following to the response headers from my server.

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

Once the browser received this response it then sent off the correct POST request with json data. It would seem that the default form-urlencoded content type is considered safe and so does not undergo the extra cross domain checks.

It looks like you will need to add the previously mentioned headers to your servers response to the OPTIONS request. You should of course configure them to allow requests from specific domains rather then all.

I used the following jQuery to test this.

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

References:

  • http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
  • http://enable-cors.org/
  • https://developer.mozilla.org/en/http_access_control
like image 70
Mike Wade Avatar answered Sep 21 '22 19:09

Mike Wade


I can show you how I used it

  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;                 }             }         });     } 
like image 45
Amritpal Singh Avatar answered Sep 20 '22 19:09

Amritpal Singh