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

(请参阅这个问题,为什么我必须使用application/json: ASPNET MVC -为什么是ModelState。当该字段有值时,该x字段是必需的?)

我怎么能让$.post()发送contentType=应用程序/json?我已经有了大量的$.post()函数,所以我不想更改为$.ajax(),因为这会花费太多时间

如果我尝试

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

它仍然有contentType=application/x-www-form-urlencoded。那么,如果“json”参数没有将内容类型更改为json,它究竟做了什么呢?

如果我尝试

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

这是可行的,但影响到每一美元。Get和$。帖子,我有和导致一些打破。

那么是否有一些方法,我可以改变$.post()的行为发送contentType=application/json?


我想你可能不得不这么做

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

Or

2.定义您自己的实用函数,它是$。您想使用的Ajax配置

Or

3.你可以覆盖$。通过monkey补丁,发布你自己的实现功能。

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


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

就像这样

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

只使用

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

更新@JK:如果你在你的问题中只写一个带有$的代码示例。你在答案中找到一个相应的例子。我不想重复同样的信息,你已经学习了,直到知道:$。Post和$。Get是$.ajax的缩写形式。所以只需使用$。Ajax,您可以使用它的全部参数集,而无需更改任何全局设置。

By the way I wouldn't recommend overwriting the standard $.post. It's my personal opinion, but for me it's important, not only that the program works, but also that all who read your program understand it with the same way. Overwriting standard methods without having a very important reason can follow to misunderstanding in reading of the program code. So I repeat my recommendation one more time: just use the original $.ajax form jQuery instead of jQuery.get and jQuery.post and you receive programs which not only perfectly work, but can be read by people without any misunderstandings.


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

参见:jQuery.ajax()


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

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

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


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

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

我知道这是一个晚的答案,我实际上有一个快捷的方法,我用来发布/读取/从基于MS的服务。它与MVC以及ASMX等工作…

Use:

$.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的情况下使用基于脚本的解析器,因为当你扩展数组和/或对象的原型时,本地解析器会中断,等等。

我一直在考虑修改这段代码以实现承诺接口,但它对我来说工作得非常好。


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

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来实现的。

谢谢!


问题的核心是,在编写本文时,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
    });

那么您自己的适配器/包装器呢?

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

目前的文档显示,在3.0,$。Post将接受Settings对象,这意味着您可以使用$。ajax选项。3.0还没有发布,在提交时,他们说要在文档中隐藏对它的引用,但以后再找吧!


我有类似的问题与以下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;utf - 8字符集= 身体:{“价值”:“5”,“执行”:“5”}

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

把最后一行改成这样:

$.post(url, rating, showSavedNotification);

在《提琴手》里我还能看到:

标题:Content-Type: application/x-www-form-urlencoded;utf - 8字符集= 身体:价值= 5 maxvalue = 10

然而,服务器开始返回我所期望的结果。


出于某种原因,在ajax请求上设置@Adrien建议的内容类型在我的情况下不起作用。但是,您实际上可以使用$更改内容类型。在发布之前这样做:

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

然后赚你的美元。post调用:

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

我有jQuery + IIS的问题,这是唯一的解决方案,帮助jQuery理解使用windows-1252编码ajax请求。


这个简单的jquery API扩展(来自:https://benjamin-schweizer.de/jquerypostjson.html)为$. postjson()做的伎俩。您可以像使用其他原生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。 你可以为承诺附加jquery的默认事件处理程序,例如:

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

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

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

美元。如果你有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) {...}
});

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

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

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

我刚刚测试了一下,它工作了!!