2012-03-17 74 views
78

当我有这样的代码无法设置内容类型为“应用/ JSON”在jQuery.ajax

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

生成奇怪的要求(我可以看到提琴手)

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 

这是为什么?什么是OPTIONS当它应该在那里?我的内容类型设置为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 

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

这里是我的小提琴手说

enter image description here

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

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

enter image description here

+1

你应该尝试JSON.stringfy()方法 – 2012-03-18 12:32:38

+0

NOP,没有帮助这里 – 2012-03-18 14:15:20

+0

看。这对我很好:http://stackoverflow.com/questions/9754767/cannot-set-content-type-to-application-json-in-jquery-ajax/18740041#18740041 – Fanda 2013-09-11 11:36:03

回答

24

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

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

与下一个答案相同。我不能不指定URL到服务器的所有服务功能托管 – 2012-03-18 14:23:07

+0

@VitaliiKorsakov我走了,你有没有理清你的问题。 – 2012-03-18 15:09:52

+0

不,看到我的第一篇文章的其他信息 – 2012-03-18 16:09:05

65

会似乎从url选项中删除http://可确保发送正确的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 sending "OPTIONS" as REQUEST_METHOD in Firefox

编辑: 一些更多的研究,我发现后的选项首部用于找出如果来自发起域的请求被允许。使用fiddler,我将以下内容添加到来自服务器的响应头文件中。

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

一旦浏览器收到这个响应,它就会发送正确的POST请求和json数据。似乎默认的表单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); 
    } 
});​ 

参考文献:

+0

我想松散客户端和服务器之间的耦合。服务器是RESTful服务,并且此服务的所有客户端都应该知道它的URL。 – 2012-03-18 14:21:42

+0

你可以提供一些关于这个问题的场景的更多细节吗?如果您的客户将在不同的域中,您可能会遇到相同的原产地问题。 – Spike 2012-03-18 14:46:49

+0

我已经发布了关于服务器端的更多信息。现在服务器和客户端都在本地主机上,但端口不同。后来他们很可能会在不同的领域。 – 2012-03-18 16:11:06

2

我发现这个问题here解决方案。不要忘记在IIS应用程序服务处理程序上允许动词选项。

工作正常。谢谢AndréPedroso。 :-)

1

我有同样的问题。我在jboss服务器上运行java rest应用程序。但我认为这个解决方案与ASP .NET webapp类似。

Firefox会预先调用您的服务器/休息网址来检查哪些选项是允许的。这是您的服务器没有相应回复的“选项”请求。如果这个OPTIONS调用被正确回复,则执行第二个调用,这是对json内容的实际“POST”请求。

这只发生在执行跨域呼叫时。在你的情况下调用'http://localhost:16329/Hello'而不是调用相同域下的url路径'/ Hello'

如果打算进行跨域调用,则必须使用带注释的方法来增强休息服务类,选项“http请求。这是相应的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") 
4

我认出那些画面,我用CodeFluentEntities,我已经有了解决方案,为工作我也是。

我使用的建设:

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

,你可以看到,如果我用

contentType: "", 

contentType: "text/plain", //chrome 

,一切工作正常。

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

8

因此,所有你需要为这个工作做的就是添加:

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

作为一个字段到您的文章请求,它会工作。

+0

http://api.jquery.com/jquery.ajax/ 如果你看看它的文档,它说,没有指定它默认为 'application/x-www-form-urlencoded; charset = UTF-8'(这就是为什么发生这种情况,Idk为什么只是设置contentType不起作用,你可能想检查你有什么版本的jQuery,如果你使用的是旧版本,就更新它)。 – 2016-01-20 16:08:47

+0

这不起作用。即使我输入:“POST”,它会发送“OPTIONS”。 – user9645 2017-08-22 14:19:46

0

如果使用这样的:

contentType: "application/json" 

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

今天花了我几个小时的时间来学习它。

只需使用:

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