无法在jQuery.ajax中将content-type设置为'application/json'

Vit*_*kov 96 jquery json content-type wcf-rest

当我有这个代码

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

在Fiddler我可以看到以下原始请求

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
Run Code Online (Sandbox Code Playgroud)

但我正在尝试的是将内容类型从application/x-www-form-urlencoded设置application/json.但是这段代码

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

生成奇怪的请求(我可以在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
Run Code Online (Sandbox Code Playgroud)

这是为什么?什么是OPTIONS什么时候应该在那里POST?我的content-type设置为application/json在哪里?并且请求参数由于某种原因而消失了.

更新1

在服务器端,我有非常简单的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

但由于某种原因,我不能用参数调用这个方法.

更新2

很抱歉没有回答这么久.

我已将这些标题添加到我的服务器响应中

 Access-Control-Allow-Origin: *
 Access-Control-Allow-Headers: Content-Type
 Access-Control-Allow-Methods: POST, GET, OPTIONS
Run Code Online (Sandbox Code Playgroud)

它没有帮助,我有来自服务器的方法不允许错误.

这是我的小提琴手所说的

在此输入图像描述

所以,现在我可以确定我的服务器接受POST,GET,OPTIONS(如果响应头像我期望的那样工作).但为什么"方法不允许"?

在服务器的WebView响应中(您可以在上面的图片中看到Raw响应)看起来像这样

在此输入图像描述

Mik*_*ade 82

似乎http://从url选项中删除可确保发送正确的HTTP POST标头.

我认为你不需要完全限定主机的名称,只需使用如下的相对URL.

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

我的一个例子:

        $.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;
        }
    });
Run Code Online (Sandbox Code Playgroud)

可能相关: jQuery $ .ajax(),$ .post在Firefox中发送"OPTIONS"作为REQUEST_METHOD

编辑: 经过一些研究后我发现OPTIONS标题用于查明是否允许来自原始域的请求.使用fiddler,我将以下内容添加到服务器的响应头中.

 Access-Control-Allow-Origin: *
 Access-Control-Allow-Headers: Content-Type
 Access-Control-Allow-Methods: POST, GET, OPTIONS
Run Code Online (Sandbox Code Playgroud)

一旦浏览器收到此响应,它就会用json数据发送正确的POST请求.似乎默认的form-urlencoded内容类型被认为是安全的,因此不会进行额外的跨域检查.

看起来您需要将以前提到的标头添加到服务器响应OPTIONS请求.您当然应该将它们配置为允许来自特定域的请求,而不是所有域.

我使用以下jQuery来测试它.

$.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);
  }
});?
Run Code Online (Sandbox Code Playgroud)

参考文献:


Amr*_*ngh 39

我可以告诉你我是如何使用它的

  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;
                }
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)


小智 11

所以你需要做的就是添加:

headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
}
Run Code Online (Sandbox Code Playgroud)

作为您的帖子请求的字段,它将工作.


Ale*_*yev 5

我认出了那些屏幕,我使用的是 CodeFluentEntities,而且我有适合我的解决方案。

我正在使用这种结构:

$.ajax({
   url: path,
   type: "POST",
   contentType: "text/plain",
   data: {"some":"some"}
}
Run Code Online (Sandbox Code Playgroud)

如你所见,如果我使用

contentType: "",
Run Code Online (Sandbox Code Playgroud)

或者

contentType: "text/plain", //chrome
Run Code Online (Sandbox Code Playgroud)

一切正常。

我不是 100% 确定这就是你所需要的,因为我也改变了标题。


小智 5

如果你使用这个:

contentType: "application/json"
Run Code Online (Sandbox Code Playgroud)

AJAX 不会向服务器发送 GET 或 POST 参数......不知道为什么。

我今天花了几个小时才学会。

只需使用:

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