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


106

当我有这个代码

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

在提琴手中,我可以看到以下原始请求

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。但是这段代码

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

生成奇怪的请求(我可以在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

这是为什么?什么时候应该将其张贴在哪里?我的内容类型在哪里设置为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;
    }
}

但是由于某种原因,我无法使用参数调用此方法。

更新2

很抱歉没有回答这么久。

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

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

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

这是我的提琴手说的

在此处输入图片说明

因此,现在我可以确定我的服务器接受POST,GET,OPTIONS(如果响应头按预期工作)。但是为什么“不允许使用方法”?

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

在此处输入图片说明


2
你应该尝试JSON.stringfy()方法
安里泊尔·辛格

看这里。这个工作对我来说非常好:stackoverflow.com/questions/9754767/...
泛达

我遇到了完全相同的问题,但是我正在使用NodeJS作为后端,同时我不仅将所有OPTION请求设置为可以接受,还对所有OPTION请求强制设置200个响应,因此其余所有请求均按预期工作没有回应...
HeberLZ 2014年

1
嗨@VitaliiKorsakov。您解决了问题吗?我遇到同样的问题,即无法修改contentType。
worldterminator 2014年

1
我有同样的问题,只是让它起作用..解决方案在此页上的答案中:stackoverflow.com/questions/20295080 / ... ..总结起来:“使用contentType:'application / json'时,您将不能依靠$ _POST填充。$ _POST仅填充表单编码的内容类型。因此,您需要从PHP原始输入中读取数据。”。我现在看到您不在服务器上使用php方面,但希望这些信息能有所帮助。
莎拉

Answers:


91

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

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

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

我的一个有效的例子:

        $.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中以REQUEST_METHOD的形式发送“ OPTIONS”

编辑: 经过更多研究后,我发现OPTIONS标头用于确定是否允许来自原始域的请求。使用提琴手,我在服务器的响应头中添加了以下内容。

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

浏览器收到此响应后,便发送带有json数据的正确POST请求。似乎默认的采用表单编码的内容类型被认为是安全的,因此不会进行额外的跨域检查。

看来您需要将前面提到的标头添加到服务器对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);
  }
});​

参考文献:


我想放松客户端和服务器之间的耦合。服务器是RESTful服务,该服务的所有客户端都应知道其网址。
Vitalii Korsakov 2012年

您能否在帖子中提供有关此问题情形的更多详细信息?如果您的客户将位于不同的域中,则可能会遇到相同的来源问题。
Mike Wade

我已经发布了有关服务器端的其他信息。现在服务器和客户端都在本地主机上,但是端口不同。以后,它们很可能将位于不同的域。
Vitalii Korsakov 2012年

似乎您遇到的问题与相同的原始策略有关,除了这些与链接相关的问题之外,还值得研究jsonp和我在答案中链接的问题jQuery跨域指南 -我对跨域请求没有太多经验,但希望这些链接对您有用。
Mike Wade 2012年

我不认为这是个问题,因为当我不传递任何参数并且content-type是application / x-www-form-urlencoded时,一切都正常。但是,如果我无法传递任何参数,则不需要POST请求。
Vitalii Korsakov 2012年

41

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

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

与下一个答案相同。我不能不指定托管所有服务功能的服务器的网址
Vitalii Korsakov 2012年

@VitaliiKorsakov我走了,请您解决问题。
Amritpal Singh 2012年

感谢你的回答!我不敢相信这不是在其他地方阐明的。当您指定的类型为'json'时,似乎JQuery似乎会发布json,但我想不是……
Jason Goemaat 2012年

1
@JasonGoemaat jQuery中的dataType参数仅用于解析返回的响应正文。如果您阅读了文档,您会发现甚至不需要它。dataType的默认值为智能猜测。您的问题是jquery中的data属性不可配置。您无法判断jquery应该如何解析数据对象。这就是为什么您必须先序列化json的原因。因为jQuery只序列化到URL形式编码
卢瓦克福雷-拉克鲁瓦

12

因此,您需要做的就是添加:

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

作为您的发帖请求的字段,它将起作用。


api.jquery.com/jquery.ajax 如果您查看文档中的内容,则表示未指定它默认为'application / x-www-form-urlencoded; charset = UTF-8'(这就是发生这种情况的原因。Idk为什么仅设置contentType仍然不起作用。您可能要检查您拥有的jQuery版本,如果使用的是旧版本,请进行更新)。
科迪·雅克

这是行不通的。即使我有type: "POST",它也在发送OPTIONS
user9645

5

我认出了这些屏幕,我正在使用CodeFluentEntities,而且我也有适用于我的解决方案。

我正在使用该构造:

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

如您所见,如果我使用

contentType: "",

要么

contentType: "text/plain", //chrome

一切正常。

我不确定100%是否满足您的所有需求,因为我还更改了标头。


5

如果使用此:

contentType: "application/json"

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

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

只需使用:

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

1
可悲的是我的正确答案。省略contentType并仅使用dataType绕过许多服务无法正确实现的CORS OPTIONS垃圾。很烦人。
Umopepisdn

2

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

工作良好。谢谢AndréPedroso。:-)


1

我遇到过同样的问题。我正在jboss服务器上运行java rest应用程序。但我认为该解决方案在ASP .NET Web应用程序上类似。

Firefox会预先调用您的服务器/剩余URL,以检查允许哪些选项。这是服务器未相应回复的“ OPTIONS”请求。如果正确回答了此OPTIONS调用,则将执行第二个调用,这是带有json内容的实际“ POST”请求。

这仅在执行跨域调用时发生。在您的情况下,调用' http://localhost:16329/Hello'而不是在同一域'/ Hello'下调用url路径

如果您打算进行跨域调用,则必须使用支持“ OPTIONS” http请求的带注释方法来增强您的REST服务类。这是根据java的实现:

@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中,您必须添加一个带有注释的附加方法

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

设置以下标头的位置

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

0

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

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


        });
    });

'Content-Type': 'text/plain'在标头中使用以发送原始json数据。
因为如果我们使用Content-Type: 'application/json'请求方法将其转换为OPTION,但是使用Content-Type: 'test/plain'该方法不会被转换并保持为POST。希望这会有所帮助。


3
它并没有真正转换为OPTION,而是发送了一个CORS预检请求,以检查是否允许POST。如果这种情况无法正确恢复,则不会发生POST。
Umopepisdn

0

嗨,这两行对我有用。

contentType:“ application / json; charset = utf-8”,dataType:“ json”

 $.ajax({
            type: "POST",
            url: "/v1/candidates",
            data: obj,
            **contentType:"application/json; charset=utf-8",
            dataType:"json",**
            success: function (data) {
                table.row.add([
                    data.name, data.title
                ]).draw(false);
            }

谢谢,Prashant

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.