最近在联调接口时发现了一个要命的问题,就是接口url
明明是正确的,但是发送就是不成功,报404异常的错误
代码
伪代码如下,一个很正常的删除数据请求
function foo(id) {
return axios({
method: 'delete',
url: '/api/resume/queue/' + id
})
}
报错
报错如下:
这里和后端一起验证过了,确实有这个接口,使用postman请求是没问题的
查资料,反复验证
然后自己写了个接口模拟了下,没有重现这个问题,请求其它 api
也都正常
接着就是查各种资料,刚开始一度以为是 delete
请求、vue-cli
的锅,查了各种资料,但还是一无所获
沉思
最后看着 DELETE http://localhost:8070/%E2%80%8B/api%E2%80%8B/resume%E2%80%8B/queue%E2%80%8B/81862404 404 (Not Found)
这一段报错信息陷入了沉思
404请求肯定是接口地址不正确的问题,但是这里的路径看着没问题(但也只是看着)
这里发现最后请求的路径加入了一些编码,也就是 %E2%80%8B
这个,然后在控制台调用 decodeURI('%E2%80%8B')
,返回 ''
空字符串,看到这里应该明白了,嗯,倒吸一口凉气...
原因
如果将光标移动到 上面 url
路径上,会发现每个/
前面需要移动两次才能跳过,其实那儿确实有一个特殊的字符,只是它没有宽度,让人误以为是什么也没有,但是如果 encodeURI
编码一下会发现确实是有东西的,也就是 %E2%80%8B
最后发现,还是因为偷懒图方便,接口地址直接从 swagger
文档那边复制过来的,而复制源里面的字符存在空白编码%E2%80%8B
,空白编码没有宽度,虽然看不到但是会导致无法精确匹配出现问题,浏览器对请求路径会自动编码,这样路径完全就不一样了,这个后端路由无法识别,当然就404了
网上查了下,%E2%80%8E
的学名叫 Zero-width-space(零宽空格)
,顾名思义,它是一个Unicode
字符,肉眼不可见,却是确实存在的一个字符
解决
- 一时复制一时爽,一直复制一直爽,你无法确认你复制的字符是否存在空白编码,所以少点复制,还是老老实实手敲一遍吧,尤其是字符串的部分
- 从开发者的角度来看,能通过代码解决的肯定更好,其实可以在发送请求之前对
url
做个正则匹配,将%E2%80%8B
替换掉
伪代码:
// 在请求发送前
url = decodeURI(encodeURI(url).replace(/%E2%80%8B/g, ''))
遇到这个问题其实挺无奈的,一个并不起眼的地方,如果你不注意,会导致你做很多无用功
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。