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

JK.*_*JK. 290 ajax jquery content-type

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

(请参阅此问题,为什么我必须使用application/json:ASPNET MVC - 为什么ModelState.IsValid为false"当该字段确实有值时,x字段是必需的?)

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

如果我试试

$.post(url, data, function(), "json") 
Run Code Online (Sandbox Code Playgroud)

它仍然有contentType = application/x-www-form-urlencoded.那么如果"json"参数没有将contenttype更改为json,那究竟该做什么呢?

如果我试试

$.ajaxSetup({
  contentType: "application/json; charset=utf-8"
});
Run Code Online (Sandbox Code Playgroud)

这有效但影响我拥有的每一个$ .get和$ .post并导致一些破坏.

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

Adr*_*ien 376

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

请参阅:jQuery.ajax()

  • 必须使用`JSON.stringify(data)`,因为服务器需要一个JSON字符串,而jQuery只需使用&符号来连接键值对,即form-urlencoded. (67认同)
  • @Adrien,两年后它的价值,你的搜索是我在谷歌搜索时的答案. (39认同)
  • 原帖子问道:"那么有什么方法可以改变$ .post()的行为来发送contentType = application/json?" 但它也说"这有效但会影响我拥有的每一个$ .get和$ .post,并导致一些破坏." 我理解这个问题是"我怎样才能实现与使用$ .post相同的功能,但是在不破坏$ .get和$ .post的其他情况下发送正确的contentType".这是不正确的? (13认同)
  • @ x1a4显然不明白.ajax是调用,而不是ajaxSetup (5认同)
  • 即使四年之后,这个答案也解决了我用不到十行代码搜索的时间. (3认同)
  • 由于jQuery v1.9 {...**类型**:"POST"...}必须替换为{...**方法**:"POST"...} (2认同)

vvk*_*wss 80

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

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

  • 无法弄清楚为什么我一直收到错误,结果你必须对数据进行字符串化. (7认同)
  • 我知道这有效,但是为什么你需要进行字符串化?这是一个jQuery错误吗?将`data`参数序列化为`x-www-form-urlencoded`似乎非常乐意,但是如果你指出请求内容类型是JSON,它仍然坚持以不匹配的格式发送`data`. (4认同)

Rus*_*Cam 67

我想你可能不得不这样做

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

要么

2. 定义您自己的实用程序功能,它是$.ajax您要使用的配置的快捷方式

要么

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

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

  • @PavelRepin,我不得不在有效负载上调用JSON.stringify(). (9认同)
  • +1,我会去定义一个新方法,或者覆盖`jQuery.post`方法,它是一个[非常简单的函数](http://github.com/jquery/jquery/blob/1.4.2/src/ajax .js文件#L143)... (5认同)
  • 这不是一个坏主意,只需创建一个名为$ .mvcpost()的方法,该方法与$ .post相同(通过复制链接代码)并更改contenttype.然后对于需要更改的所有$ .post(),我只需在前面输入3个额外字符.它比将它们重写为$ .ajax()快得多. (3认同)
  • @dragon - 这里有3个解决方案"有什么方法可以改变$ .post()的行为来发送contentType = application/json?".什么部分不是答案? (2认同)
  • 知道:$ .ajax并且它的各种方法将根据您提供的数据尝试猜测contentType应该是什么(除非它被指定),这一点也很重要.````mystring data"```将是```application/x-www-form-urlencoded;```作为对象`````{anyKey:'anyvalue and type"}```将`` ``应用/ json```.许多读取json的服务器只允许一个对象或数组,而不是一个字符串 - 这就是为什么jquery以这种方式预测事物的原因.如果您的服务器在不包含在对象中的情况下读取字符串,数字等,则必须在此答案中指定content-type. (2认同)

kon*_*ity 42

我最终在我的脚本中将以下方法添加到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
    });
};
Run Code Online (Sandbox Code Playgroud)

并使用它

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

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

谢谢!

  • 像往常一样 - 最好的答案是最后的党,最少的赞成;( (2认同)

Ole*_*leg 20

使用只是

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

UPDATED @JK:如果你在问题中只用一个代码示例一个 $ .post,你会在答案中找到一个相应的例子.我不想重复你已经研究过的相同信息,直到知道:$ .post和$ .get是$ .ajax的缩写形式.因此,只需使用$ .ajax即可使用其全部参数,而无需更改任何全局设置.

顺便说一下,我不建议覆盖标准的$ .post.这是我个人的意见,但对我而言,重要的是,不仅程序有效,而且所有阅读程序的人都以同样的方式理解它.在没有非常重要原因的情况下覆盖标准方法可能会导致在阅读程序代码时出现误解.所以,我重申我的建议更多的时间:只要使用原来的$就形成jQuery的,而不是jQuery.getjQuery.post你收到它不仅完美地工作,但可以通过人没有任何误解读程序.


Jac*_*son 8

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

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

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


Ruw*_*wen 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
  });
};
Run Code Online (Sandbox Code Playgroud)

与其他 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");
 });
Run Code Online (Sandbox Code Playgroud)


Sag*_*rac 7

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

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

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

我刚刚测试了它,它起作用了!!


Tra*_*er1 5

我知道这是一个迟到的答案,我实际上有一个快捷方法,我用它来发布/读取基于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.
  }
);
Run Code Online (Sandbox Code Playgroud)
//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));
Run Code Online (Sandbox Code Playgroud)

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

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

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


dbr*_*rin 5

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

postJSON 方法将执行以下操作:

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

并且可以这样使用:

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
    });
Run Code Online (Sandbox Code Playgroud)