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

当我有了这个密码

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

在 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

But what I'm trying is to set content-type from Application/x-www-form-urlencode to application/json. But this code

$.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

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

我的小提琴手是这么说的

enter image description here

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

In WebView response from server (you can see 生的 response on picture above) looks like this

enter image description here

444031 次浏览

我可以教你怎么用

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

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

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

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

可能有关联: jQuery $.ajax(), $.post sending "OPTIONS" as REQUEST_METHOD in Firefox

经过更多的研究,我发现 OPTION 头是用来查找是否允许来自原始域的请求。使用 fiddler,我将以下内容添加到服务器的响应头中。

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

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

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

我使用下面的 jQuery 对此进行了测试。

$.ajax({
type: "POST",
url: "http://myDomain.example/path/AddPlayer",
data: JSON.stringify({
Name: "Test",
Credits: 0
}),
//contentType: "application/json",
dataType: 'json',
complete: function(data) {
$("content").html(data);
}
});​

参考文献:

I found the solution for this problem here. Don't forget to allow verb OPTIONS on IIS app service handler.

很好,谢谢你,安德烈 · 佩德罗索

我也有同样的问题。我在 jboss 服务器上运行一个 java rest 应用程序。但是我认为在 ASP 上的解决方案是相似的。NET 网络应用程序。

Firefox 会预先调用服务器/rest URL 来检查哪些选项是允许的。这是“选项”请求,您的服务器没有相应地回复。如果这个 OPTION 调用被正确回复,那么将执行第二个调用,这是带有 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")

我认出了这些屏幕,我正在使用 CodeFluentEntities,并且我已经找到了适合我的解决方案。

我用的就是这个结构:

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

如你所见,如果我使用

contentType: "",

或者

contentType: "text/plain", //chrome

一切正常。

我不能百分之百确定这就是你所需要的,因为我还改了标题。

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

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

作为一个领域,你的职位要求,它会工作。

如果你用这个:

contentType: "application/json"

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

我今天花了好几个小时才弄明白。

只需使用:

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

我得到了通过 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 数据。
Because if we use Content-Type: 'application/json' the request methods converted to OPTION, but using Content-Type: 'test/plain' the method does not get converted and remain as POST. 希望这能帮到某人。

嗨,这两句台词对我很管用。

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

我正在解决同样的问题,它是由于缺少 JSON.stringfy ()即。

data: JSON.stringfy({ name: 'norm' }),

希望这节省了别人很多时间!

JQuery. ajax 文档中,contentType 指定要发送到服务器的内容类型。 对于跨域请求,如果设置了 application/x-www-form-urlencodedmultipart/form-datatext/plain以外的内容类型,则将在请求头中发送 OPTIONS方法。Ajax 通过 CORS 策略进行检查,以检查您请求到您的域中的服务器(在本例中为 POST)的方法是否被允许 If the OPTIONS method on your server where the API is hosted is allowed, the request you made to the server initially is made, in this case the POST is sent.

如果向同一个域和同一个端口发出请求,则不会发送 OPTIONS方法。如果是这种情况,其中一种解决方案是使用 "http://localhost:<port>..."或者只使用发出请求的相对路径。

但是如果后端的 REST API 在另一个域中,那么有两种解决方案。

  1. 不要放入 ajax contentType: "application/json",并以 JSON 格式将数据作为 Object 或字符串发送,或者作为带有要发送类型 key=value的参数的字符串发送。
  2. Enable CORS in your Rest API (that is, allow OPTIONS, POST methods, for any domain, or your domain where you make the request).

问题在于,在某些情况下,有必要将要发送的内容类型设置为 "application/json",因为承载 API 的服务器不接受其他类型的内容。

如果您可以控制 BackEnd 和 RESTAPI,我建议在它上面启用 CORS。(也适用于同一域但不同端口的情况)。

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

或者也允许其他类型的内容,如 application/x-www-form-urlencoded,或者以这样的方式编码它,即它也接受带有 key=value参数的字符串。这可以防止 jQuery 在其请求头中发送 OPTIONS

最后一件事: 如果使用 contentType: "application/json"并且服务器也期望使用 "application/json",那么应该在 data上使用 JSON.stringify(),因为当向服务器发送请求时,它似乎将 JSON 作为字符串而不是对象。在我的例子中,没有使用 JSON.stringify()和使用 contentType: "application/json",返回了一个状态为500的服务器错误