URL编码问题

URL编码问题

问题描述

需求:上传的文件不能重名,我的接口API定义为[GET] /v0.1/files?$filter=name eq xxx

问题:如果文件名称包含空格、不安全的字符、特殊的保留字符的话,后端java接收到的字符并不等价于所要传递的参数。如果文件名为a%20b.doc,那么java后台收到的name值为a b.doc,这就和预期的不一致。

解决办法

前端用encodeURIComponent编码2次,后端用URLDecoder解码两次。因为前端encodeURIComponent的一次编码是框架自己做的,后端一次URLDecoder解码是Spring做的,所以实际上只需前后端各自编码、解码一次即可。

java自带的URLEncoder是遵循RFC1738的,所以空格编码后是+而不是%20,如需转化,试用replaceAll(+,%20)即可。encodeURIComponent(” “) = %20。

原理

URLDecoder

package java.net;
public class URLEncoder extends Object

HTML表单编码的工具类。 该类包含将字符串转换为application / x-www-form-urlencoded MIME格式的静态方法。 有关HTML表单编码的更多信息,请参阅HTML规范。

编码字符串时,遵循下列规则:

  1. 字母数字字符[a-zA-Z0-9]保持不变。
  2. 特殊字符” 。”,” - “,” * “和” _ “保持不变。
  3. 空格字符” “被转换成加号”+”。
  4. 所有其他字符都是不安全的,首先使用某种编码方案将其转换为一个或多个字节。 然后每个字节由3个字符的字符串”%xy”表示,其中xy是该字节的两位十六进制表示。 推荐使用的编码方案是UTF-8。 但是,出于兼容性原因,如果未指定编码,则使用平台的默认编码。

For example using UTF-8 as the encoding scheme the string “The string ü@foo-bar” would get converted to “The+string+%C3%BC%40foo-bar” because in UTF-8 the character ü is encoded as two bytes C3 (hex) and BC (hex), and the character @ is encoded as one byte 40 (hex).

URLEncoder

package java.net;
public class URLDecoder extends Object

HTML表单解码的实用工具类。 该类包含解码application / x-www-form-urlencoded MIME格式String的静态方法。转换过程与URLEncoder类编码的过程相反。 假定编码字符串中的所有字符是下列之一:[a-zA-Z0-9
],” 。”,” - “,” * “和” _ “。 字符”%”是允许的,但被解释为特殊转义序列的开始。

html规范摘录#application/x-www-form-urlencoded

这是默认的内容类型。 使用此内容类型提交的表单必须遵循以下方式进行编码:

  1. Control names and values are escaped.
  2. Space characters are replaced by +
  3. reserved characters are escaped as described in [RFC1738], section 2.2。
  4. Non-alphanumeric characters are replaced by `%HH’, a percent sign and two hexadecimal digits representing the ASCII code of the character.
  5. 换行符被编码成encodeURIComponent("\r\n")="%0D%0A"

The control names/values are listed in the order they appear in the document. The name is separated from the value by = and name/value pairs are separated from each other by &.

This attribute specifies the content type used to submit the form to the server (when the value of method is “post”). The default value for this attribute is “application/x-www-form-urlencoded”. The value “multipart/form-data” should be used in combination with the INPUT element, type=”file”.

RFC1738规范

URL字符编码问题

URL是字符的序列,即字母([a-zA-Z])、数字([0-9])和特殊符号。一个URL可能拥有不同的表现形式。一个URL的解释取决于所用字符的特性。

多数的URL方案中,URL内不同部分的字符序列被用来表示Internet协议中使用的八字节(octet,指八个比特bit为一组的单位或一个具有八个比特的实体)序列。一个八字节可以由在US-ASCII编码字符集中具有该八字节作为其代码的字符表示。

此外,八字节可通过三元组(即%号起头,紧接着是2个十六进制的数字)的字符进行编码。

如果八字节在US-ASCII编码的字符集中没有相应的图形字符(目的是用来书写、打印或以某种方式展示的可被人类阅读的任意字符),或者使用的字符不安全,或者相应的字符被某些特定URL方案保留用于其他解释则八字节必须被编码。

没有相应的US-ASCII图形字符:URL只能用US-ASCII编码字符集内的图形打印字符编写。在US-ASCII内,八字节80-FF十六进制没有被使用,00-1F十六进制代表控制字符,这些都是必须被编码的。

不安全(unSafe):出于多种理由,字符可以是不安全的。

  • 空格是不安全的,因为有意义的空格可能会消失或当URL被抄写或排版或接受文字处理程序的处理时会引入无意义的空格。
  • < 或 >是不安全的,因为在自由文本中它们充当了分隔符。
  • 双引号(")是不安全的,因为在某些系统中,它被充当分隔符。
  • 井号#是不安全的,因为在万维网中或其他一些系统用它被用做片段或者锚点的分隔符。
  • 百分号%是不安全的,因为它别用于编码其他字符。
  • { , } , | , \ , ^ , ~ , [ , ]和`是不安全的,因为网关或者传输代理会修改这些字符。

在URL内的所有不安全的字符必须被编码。

保留的,预留的(Reserved):许多URL方案为特殊的意义保留了某些字符:它们在部分URL指定方案中出现。如果相应八字节的字符是方案内部的保留字,那它必须被编码。字符; , / , ? , : , @ , = &可能被某个方案预留用作特殊意义。在其他方案中不能保留其他字符。

当一个八字节由一个字符表示并且被编码时,URL通常具有相同的解释。 但是,对于保留字符而言,这不是真的:编码一个为特定方案保留的字符可能会改变URL的语义。

因此,在URL中数字、字母、特殊字符$ -_。+!*()以及保留字符要经过解码(unencoded)后才使用。

另一方面,只要它们不用于保留目的,可以在URL指定方案中编码不需要编码的字符(包括字母数字)。

参考

HTML规范

URLDecoder

URLEncoder

RFC1738#URL Character Encoding Issues

encodeURIComponent

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值