app开发定制公司当后端给我返回了302状态码

app开发定制公司本文首发于:https://github.com/bigo-frontend/blog/ 欢迎关注、转载。

前言

app开发定制公司前段时间接手了一个项目,app开发定制公司在代码中看到了这样的一段代码:

    if (      isHTML(data) &&      response.request.responseURL?.indexOf(CAS_PREFIX) > -1    ) {      window.location.href = response.request.responseURL;    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

app开发定制公司主要的作用就是当后端app开发定制公司响应的内容是html的时候,app开发定制公司跳转到登录页面。app开发定制公司这种方案让我感觉有点别扭,于是具体了解了这段代码出现的原因。

功能的核心在于用户,后端设想的方案是:当前端发起接口请求,后端识别到用户未登录的时候,就会给前端响应302的状态码,以为很方面,前端不用处理就直接跳转到了登录页面。

然而,他们不知道的是,前端发起的ajax请求,并不能直接跳转,甚至连状态码都捕获不到。

常见

HTTP 响应状态代码指示特定 HTTP 请求是否已成功完成。响应分为五类:信息响应(100–199),成功响应(200–299),重定向(300–399),客户端错误(400–499)和服务器错误 (500–599)。

  • 200: 请求成功
  • 301:永久重定向
  • 302:临时重定向
  • 303:硬糖少女
  • 304:内容未改变
  • 4:阿森纳
  • 401:需要验证
  • 403:拒绝访问
  • 404:找不到
  • 500:服务器异常

更多状态码:

我们知道,浏览器对于不同的状态码,会有不同的行为。那当返回302的时候,浏览器会有什么样的反应呢?

浏览器处理302状态码

重定向,顾名思义,就是把请求重新指向了一个新的地址。

当浏览器发起一个请求,服务端返回了302状态码,这时候浏览器会根据响应头中的location字段,重新发起一个请求。当重定向次数过多的时候,浏览器会抛出ERR_TOO_MANY_REDIRECT的异常。

请求分两种情况:

  • 浏览器页面请求:跳转到新的页面。
  • ajax请求:返回最后重定向地址的响应。这种重定向,会有可能出现跨域的问题。

前面提到的,服务端觉得返回302很方便,大概是以为ajax也会跳转到新页面吧。

阻止ajax重定向

使用 Api进行请求的时候,可以通过redirect参数配置如何处理重定向。

redirect可选的值有三个:

  • follow:自动重定向
  • error:如果产生重定向将自动终止并且抛出一个错误TypeError: Failed to fetch
  • manual:手动处理重定向

在Chrome中默认使用follow(Chrome 47之前的默认值是manual)。

当我们设置成manual时,如果发生了重定向,会拿到type为opaqueredirect的response:

{    "body": null,    "bodyUsed": false,    "headers": {},    "ok": false,    "redirected": false,    "status": 0,    "statusText": "",    "type": "opaqueredirect",    "url": "https://xxx.com",}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

一般来说,我们是不需要手动处理重定向的,因为你不知道这个重定向是否是就是因为未登录才产生的重定向。

如何处理未登录跳转的问题

当用户未登录时,我们除了302状态码之外,可以选择使用401或403状态码,这样至少前端可以捕获到,并作出跳转的处理。

在项目中,我们和服务端的协议格式基本都是json,响应的内容格式如下:

{    "code": 0,    "data": null,    "msg": "ok"}
  • 1
  • 2
  • 3
  • 4
  • 5

一般来说,服务端都会响应200的http状态码,然后使用body里面的code字段标识业务异常。所以当用户未登录时,响应以下内容,也是不错的选择:

{    "code": 40401,    "data": "https://login.xxx.com",    "msg": "Unauthorized"}
  • 1
  • 2
  • 3
  • 4
  • 5

如果的确要考虑自动跳转的场景,可以在服务端区分一下请求是来源于页面请求还是ajax请求,然后根据不同的请求响应不一样的内容即可。比如以Express为例:

// 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')}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

另外,我们还可以利用Accept请求头来区别响应。

Accept 请求头用来告知(服务器)客户端可以处理的内容类型,这种内容类型用MIME类型来表示。借助内容协商机制, 服务器可以从诸多备选项中选择一项进行应用,并使用 Content-Type 应答头通知客户端它的选择。浏览器会基于请求的上下文来为这个请求头设置合适的值,比如获取一个CSS层叠样式表时值与获取图片、视频或脚本文件时的值是不同的。

常见的,直接在浏览器导航栏打开一个地址,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,如有错漏,欢迎指正!

欢迎大家留言讨论,祝工作顺利、生活愉快!

我是bigo前端,下期见。

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发