URI 包含特殊字符 返回404

问题描述
在开发过程中, API采用restful的定义风格,所有的参数都放到了URL 里面,GET  v1/order/{deviceId}, 由于没有考虑到目标参数可能包含特殊字符, 所以当QA测试的时候就会发现这个scenario是failed。 调用API会返回404。其实当时设计的时候也有相关的顾虑,只是偷了一下懒, 觉得deviceId应该是标准的数据格式,不会包含特殊字符。此处略显不专业。
原因

RFC 2396标准 规定有些特殊字符在URL中是不能直接传递的.

允许的字符保留字符禁止字符
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=

/?#[]@ RFC 3986中定义的URI的泛型语法的一部分

!$&'()*+,;= 用于特定URI方案的语法组件

% 用于转义字符的编码

"<>^`{|}

解决方案

如果要在URI中传递这些特殊符号,那么就要使用他们的编码,编码的格式为百分比编码:%加字符的ASCII码,即一个百分号%,后面跟对应字符的ASCII(16进制)码值。例如 空格的编码值是"%20"。

1. 尝试直接在URL中编码 例如Url是v1/order/mydeviceid+information,进行URL编码后是v1/order/deviceId/mydeviceid%2Binformation, 似乎不工作, POSTMAIN 调用这个API 依旧报404. 网上说此处可以改配置文件去实现, 我觉得这不是一个好的注意,改config可能会引起系统安全性问题。所以pass了这种方案。

2. 尝试用queryString方式传参 v1/order?deviceid=mydeviceid+information, 进行URL编码后是v1/order?deviceid=mydeviceid%2Binformation, 这个solution是工作的,后台也能正确解析。此方法工作良好。问题解决

下面是调用API时,对参数进行URL编码,下面是常用的一些编码
CharacterCode Points (Hexadecimal)Code Points (Decimal)
Dollar ("$") 24 36
Ampersand ("&") 26 38
Plus ("+") 2B 43
Comma (",") 2C 44
Forward slash/Virgule ("/") 2F 47
Colon (":") 3A 58
Semi-colon (";") 3B 59
Equals ("=") 3D 61
Question mark ("?") 3F 63
'At' symbol ("@") 40 64

 补充

16 进制

逢16进1 一般用0-9和A-F表示, A-F相当于十进制的10-15

十六进制十进制二进制
A 10 1010
B 11 1011
C 12 1100
D 13 1101
E 14 1110
F 15 1111
 
一字节可以表示两个连续的十六进制数字
十进制转十六进制,可以采用余数定理方法转换
1. 把十进制数除以16,保留余数部分
2. 写下余数部分,在右下角标上16
3. 把之前的整数商再除以16,得到余数部分,然后再在这个余数右下角标上16
4. 重复以上步骤,直到得到一个小于16的商。每一次都把余数右下方标上16
5. 把余数和最后的商从左到右按顺序写下,最右是商。得到的十六进制就是这个数,从右往左读。比如读作2F34,实际上的值是43F2。
例如将4877下标10转成十六进制
4877÷16=304....13(D)
304÷16=19....0
19÷16=1....3
1÷16=0....1
4877下标10=130D下标16
十六进制转二进制
将一位十六进制数分解成四位二进制数,用四位二进制按权相加去凑这位十六进制数
例如D(7)H
D -> 1101
7 ->  0111
D(7)H=(11010111)B
H 代表十六进制
B 代表二进制
 

posted @ 2022-09-08 14:22  竹林溪风  阅读(213)  评论(0编辑  收藏  举报