【问题标题】:Jquery - How to make $.post() use contentType=application/json?Jquery - 如何让 $.post() 使用 contentType=application/json?
【发布时间】:2011-02-20 04:30:49
【问题描述】:

我注意到在 jquery 中使用 $.post() 时,默认 contentType 是 application/x-www-form-urlencoded - 当我的 asp.net mvc 代码需要 contentType=application/json 时

(请参阅此问题了解为什么我必须使用 application/json:ASPNET MVC - Why is ModelState.IsValid false "The x field is required" when that field does have a value?

如何让 $.post() 发送 contentType=application/json?我已经有大量的 $.post() 函数,所以我不想更改为 $.ajax() ,因为它会花费太多时间

如果我尝试

$.post(url, data, function(), "json") 

它仍然有 contentType=application/x-www-form-urlencoded。那么,如果“json”参数不将contenttype改为json,具体是做什么的呢?

如果我尝试

$.ajaxSetup({
  contentType: "application/json; charset=utf-8"
});

这可行,但会影响我拥有的每一个 $.get 和 $.post 并导致一些中断。

那么有什么方法可以改变 $.post() 的行为以发送 contentType=application/json 吗?

【问题讨论】:

    标签: jquery ajax content-type


    【解决方案1】:
    $.ajax({
      url:url,
      type:"POST",
      data:data,
      contentType:"application/json; charset=utf-8",
      dataType:"json",
      success: function(){
        ...
      }
    })
    

    见:jQuery.ajax()

    【讨论】:

    • 原帖问:“那么有什么方法可以改变 $.post() 的行为来发送 contentType=application/json 吗?”但它也指出“这有效,但会影响我拥有的每一个 $.get 和 $.post 并导致一些中断。”。我将问题理解为“我怎样才能实现与使用 $.post 相同的功能,但发送正确的 contentType 而不会破坏 $.get 和 $.post 的其他出现”。这是不正确的吗?
    • @x1a4 显然不明白 .ajax 是调用,而不是 ajaxSetup
    • @Adrien,对于两年后的价值,你的答案是我在谷歌上搜索时正在寻找的答案。
    • 必须使用JSON.stringify(data),因为服务器需要一个 JSON 字符串,而 jQuery 会简单地使用 & 符号连接键值对,form-urlencoded。
    • 即使在四年后,这个答案已经用不到十行代码解决了我的搜索时间。
    【解决方案2】:

    终于找到了适合我的解决方案:

    jQuery.ajax ({
        url: myurl,
        type: "POST",
        data: JSON.stringify({data:"test"}),
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        success: function(){
            //
        }
    });
    

    【讨论】:

    • 无法弄清楚为什么我一直收到错误,原来你必须对数据进行字符串化。
    • 我知道这行得通,但是为什么哦为什么你需要字符串化?它是一个 jQuery 错误吗?将您的data 参数序列化为x-www-form-urlencoded 似乎非常高兴,但是如果您指示请求内容类型是JSON,它仍然坚持以不匹配的格式发送data
    • 好吧。我没有挖太多。我很高兴它正在工作。 ;) 我的服务器需要 JSON。
    • 这里也一样。没有 JSON.stringify 它不起作用,我想知道为什么。
    【解决方案3】:

    我想你可能不得不

    1.修改源代码,使 $.post 始终使用 JSON 数据类型,因为它实际上只是预配置 $.ajax 调用的快捷方式

    或者

    2.Define your own utility function that is a shortcut for the $.ajax configuration you want to use

    或者

    3.您可以通过猴子修补用您自己的实现覆盖$.post function

    您示例中的 JSON 数据类型是指 服务器返回的数据类型,而不是 发送 到服务器的格式。

    【讨论】:

    • +1,我会去定义一个新方法,或者覆盖jQuery.post方法,这是一个really simple function...
    • 这不是一个坏主意,只需创建一个名为 $.mvcpost() 的方法,它的作用与 $.post 相同(通过复制链接代码)并更改内容类型。然后对于所有需要更改的 $.post()s,我只需在前面输入 3 个额外的字符。它比将它们重写为 $.ajax() 快得多。
    • @PavelRepin,我不得不在负载上调用 JSON.stringify()。
    • @dragon - 这里有 3 个解决方案来解决“有什么方法可以改变 $.post() 的行为来发送 contentType=application/json?”。哪一部分不是答案?
    • 了解以下内容也很重要:$.ajax 及其各种方法将尝试根据您提供的数据猜测 contentType 应该是什么(除非已指定)。 "mystring data" 将是 application/x-www-form-urlencoded;,其中作为对象 { anyKey: "anyvalue and type" } 将是 application/json。许多读取 json 的服务器只允许一个对象或数组,而不是一个字符串——这就是 jquery 以这种方式预测事物的原因。如果您的服务器可以读取字符串、数字等而不包含在对象中,则必须按照此答案指定内容类型。
    【解决方案4】:

    我最终在我的脚本中向 jQuery 添加了以下方法:

    jQuery["postJSON"] = function( url, data, callback ) {
        // shift arguments if data argument was omitted
        if ( jQuery.isFunction( data ) ) {
            callback = data;
            data = undefined;
        }
    
        return jQuery.ajax({
            url: url,
            type: "POST",
            contentType:"application/json; charset=utf-8",
            dataType: "json",
            data: data,
            success: callback
        });
    };
    

    并使用它

    $.postJSON('http://url', {data: 'goes', here: 'yey'}, function (data, status, xhr) {
        alert('Nailed it!')
    });
    

    这是通过简单地从原始 JQuery 源中复制“get”和“post”的代码并硬编码一些参数来强制 JSON POST 来完成的。

    谢谢!

    【讨论】:

    • 像往常一样 - 最佳答案排在最后,并且获得的支持最少;(
    • 很好的答案 - 需要一段时间才能意识到 $.post 并没有“开箱即用”。
    • 我仍然需要 JSON.stringify 围绕数据。
    【解决方案5】:

    只使用

    jQuery.ajax ({
        url: myurl,
        type: "POST",
        data: mydata,
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        success: function(){
            //
        }
    });
    

    已更新 @JK:如果您在问题中仅使用 $.post 编写一个代码示例,您会在答案中找到一个相应的示例。我不想重复您已经研究过的相同信息:$.post 和 $.get 是 $.ajax 的缩写形式。因此,只需使用 $.ajax,您就可以使用它的完整参数集,而无需更改任何全局设置。

    顺便说一下,我不建议覆盖标准的 $.post。这是我的个人意见,但对我来说,重要的是,不仅程序有效,而且所有阅读您的程序的人都以同样的方式理解它。 在没有非常重要的原因的情况下重写标准方法可能会导致在阅读程序代码时出现误解。所以我再重复一次我的建议:只需使用原始的 $.ajax 形式的 jQuery 而不是 jQuery.getjQuery.post,您就会收到不仅完美运行,而且人们可以毫无误解地阅读的程序。

    【讨论】:

    • 很好的解释和指导
    【解决方案6】:

    你猜怎么着? @BenCreasy 完全正确!!

    从 jQuery 的 1.12.0 版开始,我们可以这样做:

    $.post({
        url: yourURL,
        data: yourData,
        contentType: 'application/json; charset=utf-8'
    })
        .done(function (response) {
            //Do something on success response...
        });
    

    我刚刚测试了它并且它有效!

    【讨论】:

      【解决方案7】:

      您可以作为最后一个参数传递给 post() 的“json”数据类型表示函数在服务器响应中期望的数据类型,而不是它在请求中发送的数据类型。具体来说,它设置了“Accept”标头。

      老实说,您最好的选择是切换到 ajax() 调用。 post() 函数是为了方便;当您只是做一个简单的表单发布时,ajax() 调用的简化版本。你不是。

      如果你真的不想切换,你可以创建你自己的函数,比如 xpost(),并让它简单地将给定的参数转换为 jQuery ajax() 调用的参数,使用 content-type放。这样,您不必将所有这些 post() 函数重写为 ajax() 函数,而只需将它们全部从 post 更改为 xpost(或其他)。

      【讨论】:

      • 只有 $.post() 方法调用了 asp.net mvc 控制器方法需要更改。纯 jquery 应该保持不变(自动完成、diaplog、jqgrid 等)我希望我可以对相关的 $.post()s 进行简单的更改。但看起来我需要将它们转换为 $.ajax()。它是一个大型且非常重 ajax 的应用程序,因此有很多需要更改的地方。
      【解决方案8】:

      $.postJSON() 这个简单的 jquery API 扩展(来自:https://benjamin-schweizer.de/jquerypostjson.html)可以解决问题。您可以像使用其他所有原生 jquery Ajax 调用一样使用 postJSON()。您可以附加事件处理程序等。

      $.postJSON = function(url, data, callback) {
        return jQuery.ajax({
          'type': 'POST',
          'url': url,
          'contentType': 'application/json; charset=utf-8',
          'data': JSON.stringify(data),
          'dataType': 'json',
          'success': callback
        });
      };
      

      与其他 Ajax API(如来自 AngularJS 的 $http)一样,它将正确的 contentType 设置为 application/json。 您可以直接传递您的 json 数据(javascript 对象),因为它在此处被字符串化。 预期返回的数据类型设置为 JSON。 您可以为 promise 附加 jquery 的默认事件处理程序,例如:

      $.postJSON(apiURL, jsonData)
       .fail(function(res) {
         console.error(res.responseText);
       })
       .always(function() {
         console.log("FINISHED ajax post, hide the loading throbber");
       });
      

      【讨论】:

        【解决方案9】:

        我知道这是一个迟到的答案,我实际上有一个快捷方法,用于发布/读取基于 MS 的服务。它适用于 MVC 以及 ASMX 等...

        用途:

        $.msajax(
          '/services/someservice.asmx/SomeMethod'
          ,{}  /*empty object for nothing, or object to send as Application/JSON */
          ,function(data,jqXHR) {
            //use the data from the response.
          }
          ,function(err,jqXHR) {
            //additional error handling.
          }
        );
        //sends a json request to an ASMX or WCF service configured to reply to JSON requests.
        (function ($) {
          var tries = 0; //IE9 seems to error out the first ajax call sometimes... will retry up to 5 times
        
          $.msajax = function (url, data, onSuccess, onError) {
            return $.ajax({
              'type': "POST"
              , 'url': url
              , 'contentType': "application/json"
              , 'dataType': "json"
              , 'data': typeof data == "string" ? data : JSON.stringify(data || {})
              ,beforeSend: function(jqXHR) {
                jqXHR.setRequestHeader("X-MicrosoftAjax","Delta=true");
              }
              , 'complete': function(jqXHR, textStatus) {
                handleResponse(jqXHR, textStatus, onSuccess, onError, function(){
                  setTimeout(function(){
                    $.msajax(url, data, onSuccess, onError);
                  }, 100 * tries); //try again
                });
              }
            });
          }
        
          $.msajax.defaultErrorMessage = "Error retreiving data.";
        
        
          function logError(err, errorHandler, jqXHR) {
            tries = 0; //reset counter - handling error response
        
            //normalize error message
            if (typeof err == "string") err = { 'Message': err };
        
            if (console && console.debug && console.dir) {
              console.debug("ERROR processing jQuery.msajax request.");
              console.dir({ 'details': { 'error': err, 'jqXHR':jqXHR } });
            }
        
            try {
              errorHandler(err, jqXHR);
            } catch (e) {}
            return;
          }
        
        
          function handleResponse(jqXHR, textStatus, onSuccess, onError, onRetry) {
            var ret = null;
            var reterr = null;
            try {
              //error from jqXHR
              if (textStatus == "error") {
                var errmsg = $.msajax.defaultErrorMessage || "Error retreiving data.";
        
                //check for error response from the server
                if (jqXHR.status >= 300 && jqXHR.status < 600) {
                  return logError( jqXHR.statusText || msg, onError, jqXHR);
                }
        
                if (tries++ < 5) return onRetry();
        
                return logError( msg, onError, jqXHR);
              }
        
              //not an error response, reset try counter
              tries = 0;
        
              //check for a redirect from server (usually authentication token expiration).
              if (jqXHR.responseText.indexOf("|pageRedirect||") > 0) {
                location.href = decodeURIComponent(jqXHR.responseText.split("|pageRedirect||")[1].split("|")[0]).split('?')[0];
                return;
              }
        
              //parse response using ajax enabled parser (if available)
              ret = ((JSON && JSON.parseAjax) || $.parseJSON)(jqXHR.responseText);
        
              //invalid response
              if (!ret) throw jqXHR.responseText;  
        
              // d property wrap as of .Net 3.5
              if (ret.d) ret = ret.d;
        
              //has an error
              reterr = (ret && (ret.error || ret.Error)) || null; //specifically returned an "error"
        
              if (ret && ret.ExceptionType) { //Microsoft Webservice Exception Response
                reterr = ret
              }
        
            } catch (err) {
              reterr = {
                'Message': $.msajax.defaultErrorMessage || "Error retreiving data."
                ,'debug': err
              }
            }
        
            //perform final logic outside try/catch, was catching error in onSuccess/onError callbacks
            if (reterr) {
              logError(reterr, onError, jqXHR);
              return;
            }
        
            onSuccess(ret, jqXHR);
          }
        
        } (jQuery));

        注意:我还有一个 JSON.parseAjax 方法,它是从 json.org 的 JS 文件修改的,它添加了对 MS "/Date(...)/" 日期的处理...

        不包括修改后的 json2.js 文件,它在 IE8 的情况下使用基于脚本的解析器,因为当您扩展数组和/或对象的原型等时,本机解析器会中断。

        我一直在考虑修改此代码以实现 Promise 接口,但它对我来说非常有效。

        【讨论】:

          【解决方案10】:

          问题的核心是 JQuery 在撰写本文时没有 postJSON 方法,而 getJSON 存在并且做正确的事情。

          postJSON 方法将执行以下操作:

          postJSON = function(url,data){
              return $.ajax({url:url,data:JSON.stringify(data),type:'POST', contentType:'application/json'});
          };
          

          并且可以这样使用:

          postJSON( 'path/to/server', my_JS_Object_or_Array )
              .done(function (data) {
                  //do something useful with server returned data
                  console.log(data);
              })
              .fail(function (response, status) {
                  //handle error response
              })
              .always(function(){  
                //do something useful in either case
                //like remove the spinner
              });
          

          【讨论】:

          • 当心!顾名思义,getJSON 仅以 JSON 格式返回数据,但这并不意味着它以相同格式发送数据。当然,它在 ASP.Net MVCASP.Net API 中可以正常工作,但请尝试在 WebMethod (ASP.Net WebForms) 中使用[ScriptMethod(UseHttpGet = true)] 属性,你会感到惊讶
          【解决方案11】:

          documentation 当前显示,从 3.0 开始,$.post 将接受设置对象,这意味着您可以使用 $.ajax 选项。 3.0 还没有发布,on the commit 他们正在谈论在文档中隐藏对它的引用,但在未来寻找它!

          【讨论】:

            【解决方案12】:

            以下 JavaScript 代码有类似的问题:

            var url = 'http://my-host-name.com/api/Rating';
            
            var rating = { 
              value: 5,
              maxValue: 10
            };
            
            $.post(url, JSON.stringify(rating), showSavedNotification);
            

            Fiddler 的哪里我可以看到请求:

            • 标题:Content-Type: application/x-www-form-urlencoded; charset=UTF-8
            • 正文:{"value":"5","maxValue":"5"}

            因此,我的服务器无法将对象映射到服务器端类型。

            将最后一行改为这一行后:

            $.post(url, rating, showSavedNotification);
            

            在 Fiddler 中我仍然可以看到:

            • 标题:Content-Type: application/x-www-form-urlencoded; charset=UTF-8
            • 正文:value=5&amp;maxValue=10

            但是,服务器开始返回我所期望的。

            【讨论】:

              【解决方案13】:

              你自己的适配器/包装器怎么样?

              //adapter.js
              var adapter = (function() {
              
              return {
              
                  post: function (url, params) {
                      adapter.ajax(url, "post", params);
                      },
                  get: function (url, params) {
                      adapter.ajax(url, "get", params);
                  },
                  put: function (url, params) {
                      adapter.ajax(url, "put", params);
                  },
                  delete: function (url, params) {
                      adapter.ajax(url, "delete", params);
                  },
                  ajax: function (url, type, params) {
                      var ajaxOptions = {
                          type: type.toUpperCase(),
                          url: url,
                          success: function (data, status) {
                              var msgType = "";
                              // checkStatus here if you haven't include data.success = true in your
                              // response object
                              if ((params.checkStatus && status) || 
                                 (data.success && data.success == true)) {
                                          msgType = "success";
                                          params.onSuccess && params.onSuccess(data);
                                  } else {
                                          msgType = "danger";
                                          params.onError && params.onError(data);
                                  }
                          },
                          error: function (xhr) {
                                  params.onXHRError && params.onXHRError();
                                  //api.showNotificationWindow(xhr.statusText, "danger");
                          }
                      };
                      if (params.data) ajaxOptions.data = params.data;
                      if (api.isJSON(params.data)) {
                          ajaxOptions.contentType = "application/json; charset=utf-8";
                          ajaxOptions.dataType = "json";
                      }
                      $.ajax($.extend(ajaxOptions, params.options));
                  }
              })();
              
                  //api.js
              var api = {
                return {
                  isJSON: function (json) {
                      try {
                          var o = JSON.parse(json);
                          if (o && typeof o === "object" && o !== null) return true;
                      } catch (e) {}
                      return false;
                  }
                }
              })();
              

              而且用法极其简单:

              adapter.post("where/to/go", {
                  data: JSON.stringify(params),
                  onSuccess: function (data) {
                      //on success response...
                  }
                  //, onError: function(data) {  //on error response... }
                  //, onXHRError: function(xhr) {  //on XHR error response... }
              });
              

              【讨论】:

              • 已尝试但仍未获得预期结果。我有 Spring Boot Rest API。
              【解决方案14】:

              由于某种原因,按照@Adrien 的建议设置 ajax 请求的内容类型在我的情况下不起作用。但是,您实际上可以使用 $.post 更改内容类型,方法是:

              $.ajaxSetup({
                  'beforeSend' : function(xhr) {
                      xhr.overrideMimeType('application/json; charset=utf-8');
                  },
              });
              

              然后拨打您的$.post 电话:

              $.post(url, data, function(), "json")
              

              我在使用 jQuery + IIS 时遇到了问题,这是帮助 jQuery 理解将 windows-1252 编码用于 ajax 请求的唯一解决方案。

              【讨论】:

                【解决方案15】:

                我们可以在 $.post 中像这样改变 Content-type

                $.post(url,data, function (data, status, xhr) { xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");});

                【讨论】:

                • 我试过这个,但不幸的是它对我不起作用。 所做的工作是在 $.post 调用之前包含此 $.ajaxSetup({ contentType: "application/json; charset=utf-8" });
                【解决方案16】:

                如果您有 CORS(跨源资源共享)问题,$.post 将不起作用。尝试使用$.ajax,格式如下:

                $.ajax({
                        url: someurl,
                        contentType: 'application/json',
                        data: requestInJSONFormat,
                        headers: { 'Access-Control-Allow-Origin': '*' },
                        dataType: 'json',
                        type: 'POST',
                        async: false,
                        success: function (Data) {...}
                });
                

                【讨论】:

                  【解决方案17】:

                  您不能直接发送application/json -- 它必须是 GET/POST 请求的参数。

                  类似

                  $.post(url, {json: "...json..."}, function());
                  

                  【讨论】:

                  • 这个答案可能不正确,但质量不低,是尝试回答问题。 From Review.
                  猜你喜欢
                  • 2014-04-27
                  • 1970-01-01
                  • 2011-02-20
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-08-22
                  • 1970-01-01
                  • 1970-01-01
                  • 2018-01-24
                  相关资源
                  最近更新 更多