单页应用处理 406 状态
书接上文,上篇文章已经解决了单点登录里 session 处理的问题,这篇我们聊聊用户登出后,用户操作页面,服务返回 406 报错问题。
406 Not Acceptable
客户端出现这个状态码意味着,当前接口的返回数据没有匹配 request header
的 acceptable values
的要求,具体的配置的点如下:
Accept
:客户端支持的内容类型,用 MIME 类型表示,Accept
:<MIME_type>/<MIME_subtype>
Accept
:<MIME_type>/*
Accept
:*/*
- 实例
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8
(此处的 q 表示权重,所有值根据对应权重大小排序)
Accept-Charset
:客户端支持的字符编码,例Accept-Charset: utf-8, iso-8859-1;q=0.5, *;q=0.1
Accept-Encoding
:客户端支持的内容编码方式,- 压缩算法如 gzip、compress、deflate、br
- identity,标记支持无压缩
- *
- 例
Accept-Encoding: deflate, gzip;q=1.0, *;q=0.5
Accept-Language
:客户端支持的语言Accept-Language
:<language>
Accept-Language
:*
- 实例
Accept-Language: en-US,en;q=0.5
场景
用户当前同时开着 A、B 系统的窗口,在 B 系统中退出,在 A 系统中页面操作,请求的接口返回 406 Not Acceptable
,出现原因是服务端鉴权发现当前请求无用户状态后,直接通过 ctx.redirect('/login')
企图跳转到登录页面,但 redirect 时,请求返回内容格式就成了 HTML 格式,但客户端的 ajax 配置了 Accept: application/json;
,客户端收到了 HTML,心想这不是糊弄我吗,果断 throw 了一个 406。
方案
在后端权限校验逻辑决定 redirect 前,使用 ctx.assert(ctx.request.accepts('html'),406,'User not found. Please login!',);
判断当前请求是否支持 HTML 内容,如不支持直接服务端返回 406 错误,前端请求方法初判断返回是否是 406,返回 406 时,直接 reload 页面。
作者: leeon
来源: https://leeon.im
链接: https://leeon.im/SPA-fix-406-status-code/
本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可