ajax与302响应代码测试


Posted in Javascript onOctober 23, 2013

在ajax请求中,如果服务器端的响应是302 Found,在ajax的回调函数中能够获取这个状态码吗?能够从Response Headers中得到Location的值进行重定向吗?让我们来一起看看实际情况。
使用jquery的$.ajax()发起ajax请求的javascript代码如下:

$.ajax({
    url: '/oauth/respond',
    type: 'post',
    data: data,
    complete: function(jqXHR){
        console.log(jqXHR.status);
    },
    error: function (xhr) {
        console.log(xhr.status);
    }
});

当服务器端返回302 Found的响应时,浏览器中的运行结果如下:
 

在ajax的complete()与error()回调函数中得到的状态码都是404,而不是302。

这是为什么呢?

在stackoverflow上找到了

You can't handle redirects with XHR callbacks because the browser takes care of them automatically. You will only get back what at the redirected location.

原来,当服务器将302响应发给浏览器时,浏览器并不是直接进行ajax回调处理,而是先执行302重定向——从Response Headers中读取Location信息,然后向Location中的Url发出请求,在收到这个请求的响应后才会进行ajax回调处理。大致流程如下:
jax -> browser -> server -> 302 -> browser(redirect) -> server -> browser -> ajax callback
而在我们的测试程序中,由于302返回的重定向URL在服务器上没有相应的处理程序,所以在ajax回调函数中得到的是404状态码;如果存在对应的URL,得到的状态码就是200。
所以,如果你想在ajax请求中根据302响应通过location.href进行重定向是不可行的。

如何解决?

方法一
继续用ajax,修改服务器端代码,将原来的302响应改为json响应,比如下面的ASP.NET MVC示例代码:

return Json(new { status = 302, location = "/oauth/respond" });

ajax代码稍作修改即可:
$.ajax({
    url: '/oauth/respond',
    type: 'post',
    data: data,
    dataType: 'json',
    success: function (data) {
        if (data.status == 302) {
            location.href = data.location;
        }
    }
});

方法二
不用ajax,改用form。

<form method="post" action="/oauth/respond">
</form>

以前没研究透这个问题,踩了几次坑。这次研究了一下,我想以后就会远离这个坑了。
Javascript 相关文章推荐
如何制作浮动广告 JavaScript制作浮动广告代码
Dec 30 Javascript
jQuery中:contains选择器用法实例
Dec 30 Javascript
js中数组结合字符串实现查找(屏蔽广告判断url等)
Mar 30 Javascript
全面了解js中的script标签
Jul 04 Javascript
关于JavaScript限制字数的输入框的那些事
Aug 14 Javascript
利用jQuery插件imgAreaSelect实现获得选择域的图像信息
Dec 02 Javascript
js+html制作简单验证码
Feb 16 Javascript
兼容浏览器的js事件绑定函数(详解)
May 09 Javascript
Vue 页面切换效果之 BubbleTransition(推荐)
Apr 08 Javascript
vue中typescript装饰器的使用方法超实用教程
Jun 17 Javascript
如何提升vue.js中大型数据的性能
Jun 21 Javascript
Vue3实现简易音乐播放器组件
Aug 14 Vue.js
通过js简单实现将一个文本内容转译成加密文本
Oct 22 #Javascript
js简单实现让文本框内容逐个字的显示出来
Oct 22 #Javascript
Javascript简单实现可拖动的div
Oct 22 #Javascript
将两个div左右并列显示并实现点击标题切换内容
Oct 22 #Javascript
简单漂亮的js弹窗可自由拖拽且兼容大部分浏览器
Oct 22 #Javascript
js单例模式的两种方案
Oct 22 #Javascript
JavaScript中“过于”犀利地for/in循环使用示例
Oct 22 #Javascript
You might like
一个用php3编写的简单计数器
2006/10/09 PHP
php while循环得到循环次数
2013/10/26 PHP
PHP独立Session数据库存储操作类分享
2014/06/11 PHP
php中的抽象方法和抽象类
2017/02/14 PHP
thinkphp5框架扩展redis类方法示例
2019/05/06 PHP
PHP开发API接口签名生成及验证操作示例
2020/05/27 PHP
游戏人文件夹程序 ver 3.0
2006/07/14 Javascript
Google AJAX 搜索 API实现代码
2010/11/17 Javascript
js过滤HTML标签以及空格的思路及代码
2013/05/24 Javascript
js控制div弹出层实现方法
2015/05/11 Javascript
浅谈Javascript数组的使用
2015/07/29 Javascript
简单学习JavaScript中的for语句循环结构
2015/11/10 Javascript
JavaScript知识点总结(十)之this关键字
2016/05/31 Javascript
AngularJS入门教程之控制器详解
2016/07/27 Javascript
canvas实现探照灯效果
2017/02/07 Javascript
如何使用bootstrap框架 bootstrap入门必看!
2017/04/13 Javascript
jQuery扇形定时器插件pietimer使用方法详解
2017/07/18 jQuery
详解如何使用PM2将Node.js的集群变得更加容易
2017/11/15 Javascript
JavaScript 有用的代码片段和 trick
2018/02/22 Javascript
taro小程序添加骨架屏的实现代码
2019/11/15 Javascript
通过实例了解Render Props回调地狱解决方案
2020/11/04 Javascript
[02:11]DOTA2上海特级锦标赛主赛事第二日RECAP
2016/03/04 DOTA
Python的Django框架中forms表单类的使用方法详解
2016/06/21 Python
解决python3 urllib 链接中有中文的问题
2018/07/16 Python
Django对数据库进行添加与更新的例子
2019/07/12 Python
python-sys.stdout作为默认函数参数的实现
2020/02/21 Python
简单的命令查看安装的python版本号
2020/08/28 Python
HTML5 canvas画图并保存成图片的jcanvas插件
2014/01/17 HTML / CSS
新秀丽官方旗舰店:Samsonite拉杆箱、双肩包、皮具
2018/03/05 全球购物
岗位职责的定义
2013/11/10 职场文书
函授生自我鉴定
2014/03/25 职场文书
环保倡议书怎么写
2014/05/16 职场文书
2014和解协议书范文
2014/09/15 职场文书
稽核岗位职责
2015/02/10 职场文书
Python常遇到的错误和异常
2021/11/02 Python
vue实现在data里引入相对路径
2022/06/05 Vue.js