You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// The user needs to login againif(req.xhr){res.status(200).json({code: 40401,data: 'https://login.xxx.com',msg: "Unauthorized"})}else{res.redirect('https://login.xxx.com')}
前言
前段时间接手了一个项目,在代码中看到了这样的一段代码:
主要的作用就是当后端响应的内容是html的时候,跳转到登录页面。这种方案让我感觉有点别扭,于是具体了解了这段代码出现的原因。
功能的核心在于用户鉴权,后端设想的方案是:当前端发起接口请求,后端识别到用户未登录的时候,就会给前端响应302的状态码,以为很方面,前端不用处理就直接跳转到了登录页面。
然而,他们不知道的是,前端发起的ajax请求,并不能直接跳转,甚至连302状态码都捕获不到。
常见状态码
303:硬糖少女4:阿森纳更多状态码:传送门
我们知道,浏览器对于不同的状态码,会有不同的行为。那当返回302的时候,浏览器会有什么样的反应呢?
浏览器处理302状态码
重定向,顾名思义,就是把请求重新指向了一个新的地址。
当浏览器发起一个请求,服务端返回了302状态码,这时候浏览器会根据响应头中的location字段,重新发起一个请求。当重定向次数过多的时候,浏览器会抛出
ERR_TOO_MANY_REDIRECT
的异常。请求分两种情况:
前面提到的,服务端觉得返回302很方便,大概是以为ajax也会跳转到新页面吧。
阻止ajax重定向
使用fetch Api进行请求的时候,可以通过
redirect
参数配置如何处理重定向。redirect
可选的值有三个:follow
:自动重定向error
:如果产生重定向将自动终止并且抛出一个错误TypeError: Failed to fetch
manual
:手动处理重定向在Chrome中默认使用follow(Chrome 47之前的默认值是manual)。
当我们设置成
manual
时,如果发生了重定向,会拿到type为opaqueredirect
的response:一般来说,我们是不需要手动处理重定向的,因为你不知道这个重定向是否是就是因为未登录才产生的重定向。
如何处理未登录跳转的问题
当用户未登录时,我们除了302状态码之外,可以选择使用401或403状态码,这样至少前端可以捕获到,并作出跳转的处理。
在项目中,我们和服务端的协议格式基本都是json,响应的内容格式如下:
一般来说,服务端都会响应200的http状态码,然后使用body里面的code字段标识业务异常。所以当用户未登录时,响应以下内容,也是不错的选择:
如果的确要考虑自动跳转的场景,可以在服务端区分一下请求是来源于页面请求还是ajax请求,然后根据不同的请求响应不一样的内容即可。比如以Express为例:
另外,我们还可以利用
Accept
请求头来区别响应。常见的,直接在浏览器导航栏打开一个地址,Accept的值大概会是
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
;ajax请求,会是:Accept: application/json, text/javascript, */*; q=0.01
。其中;q= (q因子权重)
的值代表权重。更多
Accept
介绍:传送门后语
最后,点一下题。当后端给你返回了302,在他们看来,应该是这样的:
然而,在前端看来,却是这样的:
以上,简单探讨了常见又不常处理的状态码302,如有错漏,欢迎指正!
The text was updated successfully, but these errors were encountered: