昨天在调试一个ajax的时候发现,即使status是201,仍然会触发jquery的error事件。statusText是"parseerror".

通过在stackoverflow上查询,戳这里

加上参数

  1. dataType"text"

就可以解决。

而问题产生的原因在评论里写的也很详细。但是并不对,他弄错了convert的位置,在jquery判断状态码前,就已经进行了ajaxConvert。

  1. // Determine if successful,判断status的大小
  2. isSuccess = status >= 200 && status < 300 || status === 304;
  3.  
  4. // Get response data
  5. if (responses) {
  6. response = ajaxHandleResponses(s, jqXHR, responses);
  7. }
  8.  
  9. // Convert no matter what (that way responseXXX fields are always set),在此处对response的data进行转化。下面附有ajaxConvert的源码。
  10. response = ajaxConvert(s, response, jqXHR, isSuccess);
  11.  
  12. // If successful, handle type chaining
  13. if (isSuccess) {
  14.  
  15. // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  16. if (s.ifModified) {
  17. modified = jqXHR.getResponseHeader("Last-Modified");
  18. if (modified) {
  19. jQuery.lastModified[cacheURL] = modified;
  20. }
  21. modified = jqXHR.getResponseHeader("etag");
  22. if (modified) {
  23. jQuery.etag[cacheURL] = modified;
  24. }
  25. }
  26.  
  27. // if no content
  28. if (status === 204 || s.type === "HEAD") {
  29. statusText = "nocontent";
  30.  
  31. // if not modified,判断状态是否为304
  1. } else if (status === 304) {
  2. statusText = "notmodified";
  3.  
  4. // If we have data, let's convert it。
  5. } else {
  6. statusText = response.state;
  7. success = response.data;
  8. error = response.error;
  9. isSuccess = !error;
  10. }
  11. } else {
  12. // Extract error from statusText and normalize for non-aborts
  13. error = statusText;
  14. if (status || !statusText) {
  15. statusText = "error";
  16. if (status < 0) {
  17. status = 0;
  18. }
  19. }
  20. }
  1. function ajaxConvert( s, response, jqXHR, isSuccess ) {
  2. var conv2, current, conv, tmp, prev,
  3. converters = {},
  4.  
  5. // Work with a copy of dataTypes in case we need to modify it for conversion
  6. dataTypes = s.dataTypes.slice();
  7.  
  8. // Create converters map with lowercased keys
  9. if ( dataTypes[ 1 ] ) {
  10. for ( conv in s.converters ) {
  11. converters[ conv.toLowerCase() ] = s.converters[ conv ];
  12. }
  13. }
  14.  
  15. current = dataTypes.shift();
  16.  
  17. // Convert to each sequential dataType
  18. while ( current ) {
  19.  
  20. if ( s.responseFields[ current ] ) {
  21. jqXHR[ s.responseFields[ current ] ] = response;
  22. }
  23.  
  24. // Apply the dataFilter if provided
  25. if ( !prev && isSuccess && s.dataFilter ) {
  26. response = s.dataFilter( response, s.dataType );
  27. }
  28.  
  29. prev = current;
  30. current = dataTypes.shift();
  31.  
  32. if ( current ) {
  33.  
  34. // There's only work to do if current dataType is non-auto
  35. if ( current === "*" ) {
  36.  
  37. current = prev;
  38.  
  39. // Convert response if prev dataType is non-auto and differs from current
  40. } else if ( prev !== "*" && prev !== current ) {
  41.  
  42. // Seek a direct converter
  43. conv = converters[ prev + " " + current ] || converters[ "* " + current ];
  44.  
  45. // If none found, seek a pair
  46. if ( !conv ) {
  47. for ( conv2 in converters ) {
  48.  
  49. // If conv2 outputs current
  50. tmp = conv2.split( " " );
  51. if ( tmp[ 1 ] === current ) {
  52.  
  53. // If prev can be converted to accepted input
  54. conv = converters[ prev + " " + tmp[ 0 ] ] ||
  55. converters[ "* " + tmp[ 0 ] ];
  56. if ( conv ) {
  57.  
  58. // Condense equivalence converters
  59. if ( conv === true ) {
  60. conv = converters[ conv2 ];
  61.  
  62. // Otherwise, insert the intermediate dataType
  63. } else if ( converters[ conv2 ] !== true ) {
  64. current = tmp[ 0 ];
  65. dataTypes.unshift( tmp[ 1 ] );
  66. }
  67. break;
  68. }
  69. }
  70. }
  71. }
  72.  
  73. // Apply converter (if not an equivalence)
  74. if ( conv !== true ) {
  75.  
  76. // Unless errors are allowed to bubble, catch and return them
  77. if ( conv && s.throws ) {
  78. response = conv( response );
  79. } else {
  80. try {
  81. response = conv( response );
  82. } catch ( e ) {
  83. return {
  84. state: "parsererror",
  85. error: conv ? e : "No conversion from " + prev + " to " + current
  86. };
  87. }
  88. }
  89. }
  90. }
  91. }
  92. }
  93.  
  94. return { state: "success", data: response };
  95. }

p.s.在ajax的同步请求情况下,onreadystatechang事件没有触发。

p.s.jquery判断了状态204(返回空),或304(用户使用缓存文档)。

注释:

· 204 - No Content 没有新文档,浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。

· 304 - Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。

ajax的status为201依然触发jquery的error事件的问题的更多相关文章

  1. 由于想要实现下载的文件可以进行选择,而不是通过<a>标签写死下载文件的参数,所以一直想要使用JFinal结合ajax实现文件下载,但是ajax实现的文件下载并不能触发浏览器的下载文件弹出框,这里通过模拟表单提交实现同样的效果。

    由于想要实现下载的文件可以进行选择,而不是通过<a>标签写死下载文件的参数,所以一直想要使用JFinal结合ajax实现文件下载(这样的话ajax可以传递不同的参数),但是ajax实现的文 ...

  2. Ajax 跨域难题 - 原生 JS 和 jQuery 的实现对比

    讲解顺序: AJAX 的概念及由来 JS 和 jQuery 中的 ajax 浏览器机制 AJAX 跨域 AJAX 的概念 在讲解 AJAX 的概念之前,我先提一个问题. 这是一个典型的 B/S 模式. ...

  3. 解决jQuery中dbclick事件触发两次click事件

    首先感谢这位小哥!http://qubernet.blog.163.com/blog/static/1779472842011101505853216/ 太长姿势了. 在jQuery事件绑定中,dbc ...

  4. jquery的自定义事件通过on绑定trigger触发

    jquery绑定自定义事件,可以实现预先绑定好一个处理方法,当需要使用的时候利用jquery trigger来触发自定义事件,以达到方便快捷的目的.我们来假设一个这样的场景,一个textarea中的字 ...

  5. js和jquery触发按钮点击事件

    js触发按钮点击事件 function load(){ //下面两种方法效果是一样的 document.getElementById("target").onclick(); do ...

  6. click事件多次触发 jQuery

    jQuery 中 click事件会累计绑定 例如下列代码: aNode.click(function(){ bNode.click(function(){ console.log('haha'); } ...

  7. jQuery学习笔记(三)jQuery中的事件

    目录 加载DOM 事件绑定 合成事件 事件冒泡 移除事件 一.加载DOM Javascript 与HTML之间的交互是通过用户操作浏览器页面引发的事件来处理的.jQuery提供了丰富的事件处理机制.从 ...

  8. 锋利的jQuery读书笔记---jQuery中的事件

    jQuery中的事件: 1.加载DOM:注意window.onload和$(document).ready()的不同 2.事件绑定 3.合成事件 --2和3的详细信息见代码- <!DOCTYPE ...

  9. js的onclick和jquery的bind事件执行先后顺序

    近期在项目中为每一个ajax触发按钮写正在加载的效果,用的是bootstarp 代码如下 $(function(){ $('.btn').bind('click',function(e){ var $ ...

随机推荐

  1. 非域环境下使用证书部署数据库(SqlServer2008R2)镜像

    非域环境下使用证书部署数据库(SqlServer2008R2)镜像 前言 部署数据库镜像一般有两种方式域环境下部署http://liulike.blog.51cto.com/1355103/33918 ...

  2. 关于/usr/local/lib/libz.a(zutil.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC解决办法

    具体报错截图如下: 解决方法: 题外话,我对makefill cmake也是一窍不通因此本人也是不想去积极的解决这个问题,但是当你求助无缘的时候你才会静心去思考.读到这句话的时候也许你已经发现了问题所 ...

  3. 在Heroku上,安装Wordpress

    其實在 Heroku 上安裝 Wordpress 不會很難,不過閱讀之前,你可能先要知道 Heroku 與 git 的基本操作,建議可以先參考以下網站用 Heroku 架設 Wordpress 網站 ...

  4. NSDate 时间

    NSDate *date=[NSDate date]; NSDateFormatter *formatter=[[NSDateFormatter alloc]init]; formatter.date ...

  5. Spring事务管理器的应对

    Spring抽象的DAO体系兼容多种数据访问技术,它们各有特色,各有千秋.像Hibernate是非常优秀的ORM实现方案,但对底层SQL的控制不太方便:而iBatis则通过模板化技术让你方便地控制SQ ...

  6. BZOJ 1189 二分匹配 || 最大流

    1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1155  Solved: 420[Submi ...

  7. C#开发系统服务时用的定时器组件

    写服务时,都需要为定时器写不少的代码,感觉很麻烦,今天把这些代码封装一下,希望能简化一下这方面的工作,把精力都集中在功能上 本定时器组件,每次只启动一个服务实例进行处理,而不会同时多次执行服务代码. ...

  8. Const(常量)与readonly(只读)的区别

    const与readonly定义的值都不能更改,但它们到底有哪些异同点呢? Const ² Const是常量的意思,其定义的变量只能读取不能更改,且只能在定义时初始化,不能在构造函数与其它属性与方法中 ...

  9. Python学习之路二

    今天主要学习了列表,python的列表真的事太强大了,由于内容比较多,今天就先简单的介绍一下新学的几个成员函数吧. 首先我们要了解list是一种序列类型,其构造方式有四种形式: (1)空列表 [] ( ...

  10. 用PowerMock mock static方法

    在编写代码时,经常需要调用别人已经写好的工具类,而这些工具提供的方法经常是static方法,在这里,直接贴出<PowerMock实战手册>中的例子 待测试方法: public class ...