首页 文章

Jquery - 如何使$ .post()使用contentType = application / json?

提问于
浏览
270

我注意到在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?

15 回答

  • 39

    我想你可能不得不这样做

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

    要么

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

    要么

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

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

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

    见:jQuery.ajax()

  • 73

    最后我找到了适合我的解决方案:

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

    我最终在我的脚本中将以下方法添加到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来完成的 .

    谢谢!

  • 63

    使用只是

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

    UPDATED @JK:如果你用$ .post在你的问题中只写 one code example ,你会在答案中找到一个相应的例子 . 我不需要更改任何全局设置即可获得't want to repeat the same information which you already studied till know: $.post and $.get are short forms of $.ajax. So just use $.ajax and you can use the full set of it'参数 .

    顺便说一句,我不会个人意见,但对我而言,重要的是,不仅程序有效,而且所有阅读程序的人都以同样的方式理解它 . 覆盖标准方法 without having a very important reason 可以跟随 misunderstanding in reading 的程序代码 . 所以我再一次重复我的建议:只使用原始的$ .ajax形式jQuery而不是 jQuery.getjQuery.post ,你会收到的程序不仅可以完美地工作,而且可以被人阅读而不会产生任何误解 .

  • -17

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

    老实说,你最好的选择是切换到ajax()调用 . post()函数意味着方便;当你刚刚做一个简单的表单发布时,ajax()调用的简化版本 . 你不是 .

    如果你真的不想切换,你可以创建自己的函数,比如xpost(),并让它简单地将给定的参数转换为jQuery ajax()调用的参数,并设置内容类型 . 这样,你不必将所有post()函数重写为ajax()函数,而只需将它们全部从post更改为xpost(或其他) .

  • 353

    我知道这是一个迟到的答案,我实际上有一个快捷方法,我用它来发布/读取基于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的情况下使用基于脚本的解析器,因为有些实例在扩展数组和/或对象的原型等时本机解析器会中断 .

    我一直在考虑修改这个代码来实现promises接口,但它对我来说非常好用 .

  • 0

    问题的核心在于,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
        });
    
  • 2

    $ .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对象),因为它在此处进行了字符串化 . 预期返回的dataType设置为JSON . 您可以为promises附加jquery的默认事件处理程序,例如:

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

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

  • 1

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

    //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... }
    });
    
  • 5

    我在以下JavaScript代码中遇到了类似的问题:

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

    Fiddler中我可以看到请求:

    • Headers : Content-Type: application/x-www-form-urlencoded; charset=UTF-8

    • 正文: {"value":"5","maxValue":"5"}

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

    将最后一行更改为此行后:

    $.post(url, rating, showSavedNotification);
    

    在小提琴手中我仍然可以看到:

    • Headers : Content-Type: application/x-www-form-urlencoded; charset=UTF-8

    • 正文: value=5&maxValue=10

    但是,服务器开始返回我的预期 .

  • -1

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

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

    然后拨打 $.post 电话:

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

    我遇到了jQuery IIS的问题,这是帮助jQuery理解为ajax请求使用windows-1252编码的唯一解决方案 .

  • 3

    我们可以在$ .post中更改内容类型

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

  • 0

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

    所以像

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

相关问题