空格 + %20 三者的注意事项

1 篇文章 0 订阅

三者有何区别?

都表示可以空格,区别在于使用场景不同

  • %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 转义的字符多,如,’\’ 等等

可能没太讲清啊,抱歉
还是需要深入的学习

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值