我想从Swift应用程序发送一些URL编码数据到PHP API,在那里数据再次解码。
虽然这在大多数情况下都能正常工作,但我知道PHP urldecode处理+符号的方式与Swift addingPercentEncoding不同,它将+解码为空格。
如何避免这种情况?
// Swift
let data = "some+test"
let encodedData = data.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) // some+test
sendToMyServer(encodedData)
// PHP
$encodedData = $receivedData; // some+text
$decodedData = urldecode($encodedData); // some text
Swift似乎没有在任何内置(反转)char集中考虑+号:
URLFragmentAllowedCharacterSet "#%<>[\]^`{|}
URLHostAllowedCharacterSet "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet "#%<>[\]^`{|}
URLUserAllowedCharacterSet "#%/:<>?@[\]^`
PHP为什么要用这种方式处理+号?
解决这个问题的“正确”方法是什么?我假设我可以简单地定义一个包含+符号的自定义字符集,但我不确定这是否会导致其他意想不到的副作用。这是否安全,或者PHP urldecode中是否有其他需要考虑的差异?
1条答案
按热度按时间crcmnpdw1#
原因如下:
CharacterSet.urlHostAllowed
文件:返回主机URL子组件中允许的字符的字符集。
如果我们接着转到
URLComponents
的隐式链接文档此结构根据RFC 3986解析和构造URL。它的行为与URL结构的行为略有不同,后者符合旧版RFC。但是,您可以轻松地根据URLComponents值的内容获取URL值,反之亦然。
PhP
urldecode
的文档说:加号('+')被解码为空格字符。
urlencode
说道:这与RFC 3986编码(参见rawurlencode())的不同之处在于,由于历史原因,空格被编码为加号(+)。
所以iOS使用
RFC 3986
,而PhP不使用。解决方案:
使用相同的编码/解码,通过在iOS或服务器上更改它。
对于服务器更改:
要在服务器端使用与iOS相同的功能,请使用
rawurldecode
(或rawurlencode
,如果需要),如下所示:rawurldecode()不会将加号('+')解码为空格。urldecode()会。
和
rawurlencode -根据RFC 3986进行URL编码
对于iOS更改:
参见Sajjad's answer