jQuery异步请求疑问:未等待响应且$.ajax返回HTML而非JSON
问题解答
一、关于$.post的异步性与回调执行时机
首先明确:$.post默认是异步请求——调用它之后,浏览器会立刻发送请求,然后直接执行后面的代码(比如你写的$('#progress_bar').show();),不会卡在那里等服务器响应。
你觉得“并未等待响应就继续执行”,其实是指请求发送后的同步代码先跑了,但success回调本身就是专门用来等响应返回后再执行的逻辑——只有当服务器成功返回数据时,这个回调里的代码才会触发。
如果你的需求是让某些操作(比如显示进度条)也等响应回来后再做,把代码移到success(或者complete,不管请求成败都执行)回调里就行:
my.submit = function() { var form = $('#lines'); console.log(form) var data = form.serialize(); console.log(data) $.post('', form.serialize(), function(json) { console.log(json) if(json.status === 'SUCCESS') { console.log('success'); window.open(json.imgid, '_self'); } else { console.log('failure'); } // 等响应回来后再显示进度条 $('#progress_bar').show(); }, 'json'); }
如果真的要改成同步请求(非常不推荐,会阻塞浏览器,导致页面假死),可以用$.ajax并设置async: false,但优先推荐用回调/异步方式处理。
二、修改为$.ajax后返回HTML而非JSON的原因
你的修改代码犯了一个语法错误:$.ajax的参数格式不对。
$.post的第四个参数是dataType: 'json',但$.ajax需要把dataType作为配置对象的属性,而不是单独拎出来当第二个参数。你现在把'json'写在配置对象外面,jQuery会直接忽略这个参数,导致它没有按照JSON格式解析响应,自然就返回原始的HTML内容了。
正确的写法应该是:
my.submit = function() { var form = $('#lines'); console.log(form) var data = form.serialize(); console.log(data) $.ajax({ url: '', type: 'POST', data: data, dataType: 'json', // 把dataType放在配置对象内部 success: function(json) { console.log(json) if (json.status === 'SUCCESS') { console.log('Success!'); } else { console.log('An error occurred.'); console.log(data); } } }); $('#progress_bar').show(); }
另外还要检查服务器端:
- 确保返回的是合法的JSON内容,没有语法错误
- 确保响应头的
Content-Type是application/json,而不是text/html,否则jQuery也不会自动解析成JSON
内容的提问来源于stack exchange,提问作者Jabba the Hutt
相关产品推荐
相关产品推荐

