不能显式拦截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写入重定向地址, 指示浏览器跳转到登录页 浏览器跳转到登录页

操作系统中文件系统的实现和分配方式探析(下)

本文介绍了非连续空间存放方式中的两种常见形式:链式分配和索引分配。链式分配通过链表的方式实现了文件的非连续分配,其中包括了隐式链接和显式链接两种方式。隐式链接通过遍历链表来获取下一个节点的指针,适合于文件的扩展,但查找效率较低。显式链接则将指针存储在文件分配表中,提高了检索速度,但不适用于大磁盘空间。索引分配通过为每个文件创建索引数据块,实现了文件的非连续分配和直接访问。多级索引和链式索引块是处理

PerfView专题 (第十三篇):洞察 .NET程序 的非托管句柄泄露

## 一:背景 ### 1. 讲故事 前几天写了一篇 `如何洞察 .NET程序 非托管句柄泄露` 的文章,文中使用 WinDbg 的 `!htrace` 命令实现了句柄泄露的洞察,在文末我也说了,WinDbg 是以侵入式的方式解决了这个问题,在生产环境中大多数情况下是不能走附加进程的模式,所以这也是

【SQL】晨光咖啡馆,过滤聚合的微妙碰撞

这天,小悦懒洋洋地步入办公楼下的咖啡馆,意外地与一位男子不期而遇。他显然因前一晚的辛勤工作而略显疲惫,却仍选择早到此地,寻找一丝宁静与放松。他叫逸尘,身姿挺拔,衣着简约而不失格调,晨光下更显英俊不凡,吸引了周遭的目光。两人仿佛心有灵犀,不约而同地走向各自的位置。 小悦手中轻握着新出炉的拿铁,眼睛紧紧

第二届黄河流域网络安全技能挑战赛Web_wirteup

前言 好久没写过比赛的wp了,黄河流域的web出的不错,挺有意思了,花了点时间,也是成功的ak了 myfavorPython 注册登录,一个base64输入框,猜测pickle反序列化,简单测试下,返回的数据是pickletools.dis解析的opcode结构,猜测其实已经load了,但是没回显,

[转帖]Linux 异步 I/O 框架 io_uring:基本原理、程序示例与性能压测

io_uring是 2019 年 Linux 5.1内核首次引入的高性能异步 I/O 框架,能显着加速 I/O 密集型应用的性能。但如果你的应用已经在使用传统 Linux AIO 了,并且使用方式恰当, 那io_uring并不会带来太大的性能提升—— 根据测试,即便打开高级特性,也只有 5%。除非你

分拣平台API安全治理实战 | 京东物流技术团队

导读 本文主要基于京东物流的分拣业务平台在生产环境遇到的一些安全类问题,进行定位并采取合适的解决方案进行安全治理,引出对行业内不同业务领域、不同类型系统的安全治理方案的探究,最后笔者也基于自己在金融领域的经验进行了关于API网关治理方案的分享。 写在前面 随着互联网应用的多元化、复杂化、服务化成为显

口播神器,基于Edge,微软TTS(text-to-speech)文字转语音免费开源库edge-tts实践(Python3.10)

不能否认,微软Azure在TTS(text-to-speech文字转语音)这个人工智能细分领域的影响力是统治级的,一如ChatGPT在NLP领域的随心所欲,予取予求。君不见几乎所有的抖音营销号口播均采用微软的语音合成技术,其影响力由此可见一斑,仅有的白璧微瑕之处就是价格略高,虽然国内也可以使用科大讯

TS不能将类型“any[]”分配给类型“never[]”

一、问题 在处理接口返回的数据,赋值给store中的数组时,报类型错误 data:{ cateList: [] } const getCateList = async () => { const res = await fetchCateList() as any if (res.code == 2

聊一聊 SQLSERVER 的行不能跨页

一:背景 1. 讲故事 相信有很多朋友在学习 SQLSERVER 的时候都听说过这句话,但大多都是记忆为主,最近在研究 SQLSERVER,所以我们从 底层存储 的角度来深入理解下。 二:理解数据页 1. 数据页的组织 在前面的文章中我也说过,一个 数据页 是 8k 大小,那这 8k 是如何组织的呢