不能显式拦截ajax请求的302响应?

不能,拦截,ajax,请求,响应 · 浏览次数 : 16

小编点评

**小案例:ajax请求不能显式拦截302响应** **背景:** 我们先来看一个常规的登录case:浏览器请求资源,服务器发现该请求未携带相关凭据(cookie或者token)服务器响应302,并在响应头Location写入重定向地址, 指示浏览器跳转到登录页浏览器跳转到登录页,提交身份信息,回调到原业务站点,服务端利用Set-Cookie响应头种下cookie或者token利用axios库发起请求:Axios is a promise-based HTTP Client for node.js and the browser. It is isomorphic (= it can run in the browser and nodejs with the same codebase). **问题:** On the client (browser) side, when an HTTP request is made with axios, the library returns a promise. If the request is successful (i.e. the server responds with a 2xx status code), the promise will be resolved and the then() callback will be called with the response data. On the other hand, if the request fails (i.e. the server responds with a 4xx or 5xx status code), the promise will be rejected and the catch() callback will be called with the error. **解决方案:** 在上面伪代码中,我们增加了 `validateStatus` 配置来显式拦截 302响应。`validateStatus` 函数接受响应状态码作为参数,并返回一个布尔值,指示请求是否应该继续执行。 `axios.request({...}).then((resp) => {...})` 响应成功时调用 `then()`回调,并将响应数据作为参数传递给 `res.data`。 `axios.request({...}).catch((err) => {...})` 响应失败时调用 `catch()` 错误回调,并将错误信息作为参数传递给 `err.response`。 通过添加 `validateStatus` 配置,我们能够显式拦截 302响应,并将响应结果存储在 `resp.data` 中。如果响应状态码是 302,则将重定向后的页面的地址存储在 `window.location.href` 中。

正文

记录工作中早该加深印象的一个小case: ajax请求不能显式拦截 302响应。

我们先来看一个常规的登录case:

  1. 浏览器请求资源,服务器发现该请求未携带相关凭据(cookie或者token)
  2. 服务器响应302,并在响应头Location写入重定向地址, 指示浏览器跳转到登录页
  3. 浏览器跳转到登录页,提交身份信息,回调到原业务站点,服务端利用Set-Cookie响应头种下cookie或者token

利用axios库发起请求

Axios is a promise-based HTTP Client for node.js and the browser. It is isomorphic (= it can run in the browser and nodejs with the same codebase). On the server-side it uses the native node.js http module, while on the client (browser) it uses XMLHttpRequests.

When you make an HTTP request with axios, the library returns a promise. If the request is successful (i.e. the server responds with a 2xx status code), the promise will be resolved and the then() callback will be called with the response data. On the other hand, if the request fails (i.e. the server responds with a 4xx or 5xx status code), the promise will be rejected and the catch() callback will be called with the error.

  1. axios在浏览器发起的是ajax请求
  2. axios默认认为2xx状态码是成功的响应, 会进入promise的resolved回调函数, 本case第一次会收到302重定向响应, 故添加ValidateStatus配置

伪代码如下:

   axios.request({
       method:'get',
       url:'/login',
       validateStatus: function (status) {
                return status >= 200 && status < 300 || status === 302; 
       },
   }).then((resp)=> {
     if resp.status ===302 {
         window.location.href = resp.headers['Location']
      }else{
        var userInfo = JSON.parse(
                    decodeURIComponent(
                        resp.data.msg || ""
                    ) || "{}"
                )
        this.setState({
              userInfo
        })
     }
   })

实际上以上ajax请求收到的302响应并不能被显式拦截,上面的resp实际是redirect之后的页面的响应体

核心在于:所有浏览器都遵循了ajax标准readystatus=2, All redirects (if any) have been followed and all headers of a response have been received.

翻译下来就是 : ajax收到的响应如果有重定向,必然是重定向逻辑走完之后的响应。


对于这个常规的case, github上给出的思路是: 针对不同类型的http请求,服务端给出不同的状态码。

  if  req.isXhr {
     c.JSON(http.StatusForbidden, gin.H{
          "code": 403,
          "msg":  redirectUrl}) 
  }else {
      c.Redirect(http.StatusFound, redirectUrl)
  }

如果是ajax请求,返回4xx json响应,让浏览器主动重定向。

 axios.defaults.headers.common['X-Requested-With']="XMLHttpRequest";
 axios.request({    
            method: 'get',
            url: '/login',
            validateStatus: function (status) {
                return status >= 200 && status < 300 || status === 403; 
            },
        }).then((resp)=> {
            if (resp.status===200  && resp.data.code === 200) {
               ......
            }else{
                window.location.href = resp.data.msg
            }
        })   

与不能显式拦截ajax请求的302响应?相似的内容:

不能显式拦截ajax请求的302响应?

记录工作中早该加深印象的一个小case: ajax请求不能显式拦截 302响应。 我们先来看一个常规的登录case: 浏览器请求资源,服务器发现该请求未携带相关凭据(cookie或者token) 服务器响应302,并在响应头Location写入重定向地址, 指示浏览器跳转到登录页 浏览器跳转到登录页

[转帖]Linux流控框架:TC和Netfilter

https://www.jianshu.com/p/de30bac5b893 Linux内核内置了一个Traffic Control框架,可以实现流量限速,流量整形,策略应用(丢弃,NAT等)。从这个框架你能想到别的什么吗?或许现在不能,但是我会先简单说一下,和TC框架比较相似的是Netfilter

wxdown 公众号离线文章保存(GO语言开发)

简介 本来一开始用 nodejs 写的,考虑大小、易操作、高性能、跨平台以及环境等问题,我就想能不能搞个不需依赖开发语言环境就能运行的。所以我就选择 go并且它本身就具备以上优点。作者本身是java开发,第一次使用 go所以过程也是比较艰难,好在 GPT 在学习一门新的开发语言方面还是相当给力!

iPhone 使用类ChatGPT应用的几种方法

# iPhone 使用类ChatGPT功能的几种方法 ## 背景 ``` 前几天使用edge的wetab的插件给自己的工作带来了很多帮助 尤其是一些基础shell语法以及sql语法, 比使用百度, bing 等搜素引擎更加方便快捷. 当时一直想能不能在手机上面也使用这样的软件. 当然了, 这个帖子仅

【23种设计模式】组合模式(八)

前言 组合模式,英文名称是:Composite Pattern。当我们谈到这个模式的时候,有一个物件和这个模式很像,也符合这个模式要表达的意思,那就是“俄罗斯套娃”。“俄罗斯套娃”就是大的瓷器娃娃里面装着一个小的瓷器娃娃,小的瓷器娃娃里面再装着更小的瓷器娃娃,直到最后一个不能再装更小的瓷器娃娃的那个

在HTML中引入React和JSX

## 前言 Vue 可以非常方便地与 Pure HTML 结合,代替 jQuery 的功能,有一次遇到类似的场景时,我就想 React 能不能也以这种方式接入 HTML 网页,从而提高开发效率。 结果当然是可以的,只不过在 HTML 里直接 JSX 似乎会降低一些性能… 凑合用吧 ## 引入依赖 要

debug技巧之远程调试

一、前言 大家好啊,我是summo,今天给大家分享一下我平时是怎么调试代码的,不是权威也不是教学,就是简单分享一下,如果大家还有更好的调试方式也可以多多交流哦。 当我们的应用发布到线上之后,就不能随意启停了,但如果线上出现了BUG怎么办呢?大多数时候我们会借助线上打印的日志进行排查问题,如果幸运的话

云间玉兔,自出机抒,从零开始制作Web插件网页特效小兔子组件(小挂件widget),基于原生CSS/NPM

著意登楼瞻玉兔,何人张幕遮银阙?又到了一年一度的网页小挂件环节,以往我们都是集成别人开源的组件,但所谓熟读唐诗三百首,不会做诗也会吟,熟读了别人的东西,做几首打油诗也是可以的,但若不能自出机抒,却也成不了大事,所以本次我们从零开始制作属于自己的网页小挂件,博君一晒。 玉兔主题元素绘制 成本最低的绘制

对于小程序canvas在某些情况下touchmove 不能连续触发导致的签名不连续替代方案(企微)

1.问题 微信开放社区链接 尝试过新版canvas,在企业微信中签名依然是依然断触,有问题的手机是iphoe15,系统版本以及企微版本微信版本均与签名正常的手机一致,但是那个手机就是无法正常签字,在微信中无论新旧canvas均能正常签字 2.解决方案 既然canvas的touchmove触发有问题,

我第一个开源AI小产品-video2blog即将正式发布

前言 首先它是为了解决我自己的个人问题。不管能不能帮到你,或者对于看到的你是否有点利用价值,也没太大的关系,最起码你可以来看看我开发小产品的整个过程。 一段时间以来,我开始通过youtube平台来获取一些知识,或者打发早晚上下班坐地铁的时间。主要是我早晚通勤时间过长,差不多都是一个小时吧,单纯的刷刷