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
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
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
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;
}
}
});
}
So all you need to do for this to work is add:
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
as a field to your post request and it'll work.
I recognized those screens, I'm using CodeFluentEntities, and I've got solution that worked for me as well.
I'm using that construction:
$.ajax({
url: path,
type: "POST",
contentType: "text/plain",
data: {"some":"some"}
}
as you can see, if I use
contentType: "",
or
contentType: "text/plain", //chrome
Everything works fine.
I'm not 100% sure that it's all that you need, cause I've also changed headers.
If you use this:
contentType: "application/json"
AJAX won't sent GET or POST params to the server.... dont know why.
It took me hours to lear it today.
Just Use:
$.ajax(
{ url : 'http://blabla.com/wsGetReport.php',
data : myFormData, type : 'POST', dataType : 'json',
// contentType: "application/json",
success : function(wsQuery) { }
}
)