空格 + %20 三者的注意事项
最编程
2024-01-01 22:40:29
...
三者有何区别?
都表示可以空格,区别在于使用场景不同
- %20 用在 URL 的路径部分,如 xxx.com/%20abc/haha.htm,而如果写成 xxx.com/+abc/haha.htm,是不会正确识别的,直接空格更是不行(平时浏览器都替我们转换了),路径部分 %20 表示空格
package main
import (
"github.com/gin-gonic/gin"
)
// 测试代码,路径带空格
func main() {
a := gin.Default()
a.GET("/ asd", func(ctx *gin.Context) {
ctx.JSON(200, gin.H{})
})
a.Run(":8000")
}
可以看出,在路径部分不存在赤裸裸的空格,只有 %20 表示空格,’+’ 在这里就是 ‘+’
- URL 中的查询部分
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
// 测试代码,参数值带空格
func main() {
a := gin.Default()
a.GET("/", func(ctx *gin.Context) {
q := ctx.Query("q")
fmt.Println(q)
ctx.JSON(200, gin.H{})
})
a.Run(":8000")
}
可以看到,查询部分依旧不能出现赤裸裸的空格,只能是 ‘+’ 或 %20
这里看到 ‘+’ 和 %20 都被解析为空格(%2B 表示 ‘+’ ),所以得出结论,查询部分的 参数值 都可以用这两种方式来表示空格。
所以参数值如果带有真正意义上的加号需要先正确的转义
注意 javaScript encodeURI 和 encodeURIComponent 是不同的(转义字符多少的区别)
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
// 测试代码,参数前带空格
func main() {
a := gin.Default()
a.GET("/", func(ctx *gin.Context) {
q := ctx.Query(" q")
fmt.Println(q)
ctx.JSON(200, gin.H{})
})
a.Run(":8000")
}
依旧,赤裸裸的空格不能有( HTTP 协议嘛 )
参数名支持 %20
参数名支持 ‘+’
所以,参数名也都支持两种方式
- 为什么会这样?
答:是协议这样规定的,W3C 说参数名和参数值要用 + 来表示空格,RFC 2396 说我们就全用 %20 来表示空格吧。所以就是说没有强有力的统一协议来规定,在服务端实现就把 ‘+’ 默认识别成空格了
所以,结论是?
-
路径部分基本上不出现空格等情况,平时主要考虑参数部分
-
如果我们作为请求发送方:
空格用 %20 就对了,如果字符包含了 + 等等特殊字符(在实际使用中具有其他语义),去转义,使用严格的转义来确保消息的正确传达
- 如果作为服务提供者:
没啥值得考虑的,一般来说,语言层面都做好了,也基本上是要求严格转义的(加号算空格)
- 一般来说只在发送方需要思考转义的问题,再发送的时候选择合适的函数来就可以了(一般语言都提供多种程度的转义函数,如 js,go 等等)
encodeURI 和 encodeURLComponent 区别
转义程度不同,encodeURLComponent 转义的字符多,如,’\’ 等等
可能没太讲清啊,抱歉
还是需要深入的学习
推荐阅读