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

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

当我有这个密码的时候

1
2
3
4
5
6
7
$.ajax({
    type: 'POST',
    //contentType:"application/json",
    url: 'http://localhost:16329/Hello',
    data: { name: 'norm' },
    dataType: 'json'
});

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

但我尝试将内容类型从application/x-www-form-urlencoded设置为application/json。但是这个代码

1
2
3
4
5
6
7
$.ajax({
    type:"POST",
    contentType:"application/json",
    url: 'http://localhost:16329/Hello',
    data: { name: 'norm' },
    dataType:"json"
});

生成奇怪的请求(在fiddler中可以看到)

1
2
3
4
5
6
7
8
9
10
11
12
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

为什么会这样?什么是选项,当它应该张贴在那里?我的内容类型在哪里设置为application/json?请求参数由于某种原因而消失。

更新1

在服务器端,我有非常简单的RESTful服务。

1
2
3
4
5
6
7
8
9
10
11
12
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class RestfulService : IRestfulService
{
    [WebInvoke(
        Method ="POST",
        UriTemplate ="Hello",
        ResponseFormat = WebMessageFormat.Json)]
    public string HelloWorld(string name)
    {
        return"hello," + name;
    }
}

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

更新2

很抱歉这么久没回答。

我已将这些头添加到服务器响应中

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

它没有帮助,我有方法不允许从服务器出错。

这是我的小提琴手说的话

enter image description here

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

在服务器的WebView响应中(您可以在上图中看到原始响应),如下所示

enter image description here


从url选项中删除http://似乎可以确保发送正确的http-post头。

我认为您不需要完全限定主机名,只需使用下面的相对URL即可。

1
2
3
4
5
6
7
   $.ajax({
      type:"POST",
      contentType:"application/json",
      url: '/Hello',
      data: { name: 'norm' },
      dataType:"json"
   });

我的一个例子是:

1
2
3
4
5
6
7
8
9
10
11
        $.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;
        }
    });

可能相关:jquery$.ajax(),$.post作为firefox中的请求方法发送"选项"

编辑:在做了更多的研究之后,我发现了选项头用于确定是否允许来自原始域的请求。使用fiddler,我将以下内容添加到服务器的响应头中。

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

一旦浏览器收到这个响应,它就会发送带有JSON数据的正确POST请求。似乎默认形式的urlencoded内容类型是安全的,因此不需要进行额外的跨域检查。

看起来您需要将前面提到的头添加到服务器中,以响应选项请求。当然,您应该将它们配置为允许来自特定域的请求,而不是全部请求。

我使用下面的jquery来测试这一点。

1
2
3
4
5
6
7
8
9
10
11
12
13
$.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);
  }
});?

参考文献:

  • http://www.w3.org/protocols/rfc2616/rfc2616-sec9.html
  • 网址:http://enable-cors.org/
  • https://developer.mozilla.org/en/http_访问控制


我可以告诉你我是怎么用的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  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;
                }
            }
        });
    }


所以你要做的就是增加:

1
2
3
4
headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
}

作为你的职位申请的一个字段,它将起作用。


我认出了那些屏幕,我使用的是共同流畅性,我也找到了适合我的解决方案。

我用的是那种结构:

1
2
3
4
5
6
$.ajax({
   url: path,
   type:"POST",
   contentType:"text/plain",
   data: {"some":"some"}
}

如你所见,如果我使用

1
contentType:"",

1
contentType:"text/plain", //chrome

一切正常。

我不能百分之百地肯定这是你所需要的,因为我也改变了标题。


我在这里找到了这个问题的解决方案。不要忘记在IIS应用服务处理程序上允许动词选项。

工作良好。谢谢安德烈·佩德罗索。-)


如果您使用:

1
contentType:"application/json"

Ajax不会向服务器发送get或post参数…不知道为什么。

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

只需使用:

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


我也有同样的问题。我正在JBASS服务器上运行Java REST应用程序。但我认为这个解决方案在ASP.NET Web应用程序上是相似的。

火狐会预先调用你的服务器/rest url来检查允许哪些选项。这是服务器没有相应回复的"选项"请求。如果这个选项调用得到了正确的响应,那么将执行第二个调用,即带有JSON内容的实际"post"请求。

只有在执行跨域调用时才会发生这种情况。在您的情况下,调用"EDOCX1"(1),而不是在同一域下调用URL路径"/hello"

如果要进行跨域调用,则必须使用带注释的方法增强REST服务类,该方法支持"选项"HTTP请求。这是根据Java实现的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@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();
    }
}

所以我猜在.NET中,你必须添加一个附加的方法

1
2
3
4
[WebInvoke(
        Method ="OPTIONS",
        UriTemplate ="Hello",
        ResponseFormat = WebMessageFormat.)]

设置以下标题的位置

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

我得到了通过jquery ajax通过post请求发送JSON数据的解决方案。我用了下面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    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 );
      });


        });
    });

我在header中使用EDOCX1[2]发送原始JSON数据。因为如果我们使用Content-Type: 'application/json',请求方法会转换为选项,但是使用Content-Type: 'test/plain',方法不会被转换并保留为post。希望这能对某些人有所帮助。