无法在 jQuery.ajax 中将内容类型设置为“应用程序/json”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9754767/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 11:15:44  来源:igfitidea点击:

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

jsonjquerycontent-typewcf-rest

提问by Vitalii Korsakov

When I have this code

当我有这个代码

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

in Fiddler I can see following raw request

在 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-urlencodedto application/json. But this code

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

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

Generates strange request (which I can see in Fiddler)

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

Why is that? What is OPTIONS when it should be POST there? And where is my content-type set to application/json? And request parameters has gone for some reason.

这是为什么?当它应该在那里发布时,OPTIONS 是什么?我的内容类型在哪里设置为 application/json?并且请求参数由于某种原因消失了。

UPDATE 1

更新 1

On server side I have really simple RESTful service.

在服务器端,我有非常简单的 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;
    }
}

But for some reason I can't call this method with parameters.

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

UPDATE 2

更新 2

Sorry for not answering so long.

抱歉这么久没有回复。

I've added these headers to my server response

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

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

It didn't help, I have Method not allowederror from server.

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

Here is what my fiddler says

这是我的小提琴手说的

enter image description here

在此处输入图片说明

So, now I can be sure that my server accepts POST, GET, OPTIONS(if response headers work like I expect). But why "Method not allowed"?

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

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

在来自服务器的 WebView 响应中(您可以在上图中看到原始响应)看起来像这样

enter image description here

在此处输入图片说明

回答by Mike Wade

It would seem that removing http://from the url option ensures the the correct HTTP POST header is sent.

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

I dont think you need to fully qualify the name of the host, just use a relative URL as below.

我认为您不需要完全限定主机的名称,只需使用如下的相对 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;
        }
    });

Possibly related: jQuery $.ajax(), $.post sending "OPTIONS" as REQUEST_METHOD in Firefox

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

Edit:After some more research I found out the OPTIONS header is used to find out if the request from the originating domain is allowed. Using fiddler, I added the following to the response headers from my server.

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

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

Once the browser received this response it then sent off the correct POST request with json data. It would seem that the default form-urlencoded content type is considered safe and so does not undergo the extra cross domain checks.

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

It looks like you will need to add the previously mentioned headers to your servers response to the OPTIONS request. You should of course configure them to allow requests from specific domains rather then all.

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

I used the following jQuery to test this.

我使用以下 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);
  }
});?

References:

参考:

回答by Amritpal Singh

I can show you how I used it

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

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

回答by Cody Jacques

So all you need to do for this to work is add:

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

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

as a field to your post request and it'll work.

作为您发布请求的字段,它会起作用。

回答by Luis Arturo Erique Guajala

If you use this:

如果你使用这个:

contentType: "application/json"

AJAX won't sent GET or POST params to the server.... dont know why.

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

It took me hours to lear it today.

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

Just Use:

只需使用:

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

回答by Alexey Avdeyev

I recognized those screens, I'm using CodeFluentEntities, and I've got solution that worked for me as well.

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

I'm using that construction:

我正在使用这种结构:

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

as you can see, if I use

如你所见,如果我使用

contentType: "",

or

或者

contentType: "text/plain", //chrome

Everything works fine.

一切正常。

I'm not 100% sure that it's all that you need, cause I've also changed headers.

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

回答by Fanda

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

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

Works fine. Thank you André Pedroso. :-)

工作正常。谢谢安德烈·佩德罗索。:-)

回答by Vincent

I had the same issue. I'm running a java rest app on a jboss server. But I think the solution is similar on an ASP .NET webapp.

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

Firefox makes a pre call to your server / rest url to check which options are allowed. That is the "OPTIONS" request which your server doesn't reply to accordingly. If this OPTIONS call is replied correct a second call is performed which is the actual "POST" request with json content.

Firefox 会预先调用您的服务器/rest url 以检查允许使用哪些选项。这是您的服务器不会相应回复的“选项”请求。如果此 OPTIONS 调用得到正确答复,则会执行第二个调用,这是具有 json 内容的实际“POST”请求。

This only happens when performing a cross-domain call. In your case calling 'http://localhost:16329/Hello' instead of calling a url path under the same domain '/Hello'

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

If you intend to make a cross domain call you have to enhance your rest service class with an annotated method the supports a "OPTIONS" http request. This is the according java implementation:

如果您打算进行跨域调用,则必须使用支持“OPTIONS”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();
    }
}

So I guess in .NET you have to add an additional method annotated with

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

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

where the following headers are set

其中设置了以下标题

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

回答by Rahul Aparajit

I got the solution to send the JSON data by POST request through jquery ajax. I used below code

我得到了通过 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 );
      });


        });
    });

I used 'Content-Type': 'text/plain'in header to send the raw json data.
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. Hopefully this will help some one.

'Content-Type': 'text/plain'在 header 中使用来发送原始 json 数据。
因为如果我们使用Content-Type: 'application/json'请求方法转换为 OPTION,但使用Content-Type: 'test/plain'该方法并没有得到转换并保持为 POST。希望这会帮助某人。