问题背景

接收客户端传入参数,base64解码失败,经过排查发现原因是参数上传前字符串中有+,但是PHP接收后,发现+变成了空格,导致base64解码失败。

测试验证

访问一个测试的接口 /internal/test

curl 'http://127.0.0.1/internal/test?a=abc+def'

验证1:

简单输出$_GET

public function test() {

var_dump($_GET);

}

结果:

array(1) {

["a"]=>

string(7) "abc def"

}

结论:可以看到直接接收GET参数,+变成了空格

+变成空格的原因

经过一顿查资料,首先我们要知道URL编码是什么

URL编码

一个例子

我们常见的一个URL,例如CSDN搜索功能的一个URL(https://so.csdn.net/so/search/s.do?q=PHP基于字典树算法实现搜索联想功能&t=&u=),当你从浏览器中复制出来的时候,这个URL长下面这样子 https://so.csdn.net/so/search/s.do?q=PHP%E5%9F%BA%E4%BA%8E%E5%AD%97%E5%85%B8%E6%A0%91%E7%AE%97%E6%B3%95%E5%AE%9E%E7%8E%B0%E6%90%9C%E7%B4%A2%E8%81%94%E6%83%B3%E5%8A%9F%E8%83%BD&t=&u=

这就是URL被编码了,这里编码是将中文转换成了%开头的两个十六进制数。

为什么URL会被编码呢?

URL中的参数部分是由一个个key=value的参数对组成,而如果&=/?等在URL具有一定功能的特殊字符出现在key或者value中时,就会导致语义出现不一致的情况,例如参数q的值是a&b,那么当出现q=a&b&f=s这样一个参数对时,是表示q的值是a&b,还是q的值是a,而b的值为空呢?

因此需要对URL进行编码,这样被编码过的字符就不再会有歧义,上面例子中的q=a&b&f=s会被编码成q=a%26b&f=s,你看这样是不是就不会混乱了。

如何对URL进行编码呢?

URL如何进行编码由RFC标准进行规定,

在RFC-1738对URL进行说明的各项标准中,提出了要对URL中不安全的字符进行编码,编码方式即使用%和紧跟的两个十六进制数字表示,注意在该标准中空格被编码成+

在升级版RFC-2396对URI进行说明的各项标准中,再次提到了对参数进行编码,注意在在该标准中空格被编码成%20

在再次升级版的RFC-3986标准中,对Url的编解码问题做出了更加详细的建议,指出了哪些字符需要被编码才不会引起Url语义的转变,以及对为什么这些字符需要编码做出了相应的解释。

回头来研究下一开始的问题

通过以上的资料,我们可以看出来+被变成了空格的原因,正是按照RFC-1738标准进行的反编码,也就是.PHP接收$_GET参数遵循的是的是RFC-1738标准。

所以直接读取$_GET时,+就反过来被解码成了空格

怎么解决这个问题

那我们怎么让PHP不按照RFC-1738标准进行解码,而是按照升级版的RFC-3986标准进行解码呢?

最简单的办法当然是让+以正确的方式进行编码,也就是在客户端请求接口时,按照RFC-3986标准进行对URL进行编码。此时+被编码成%2b,当PHP接收参数时,将%2b解码成+,大功告成。

验证结果

对URL进行正确的编码

curl 'http://127.0.0.1/internal/test?a=abc%2bdef'

此时可以看到接口输出

array(1) {

["a"]=>

string(7) "abc+def"

}

PHP语言里还有别的坑吗?

除了接收$_GET参数外,PHP中还有对URL参数处理的两个常用的函数urlencode和urldecode。

注意这两个函数也是遵循RFC-1738进行编码和解码,从官网的说明可以看到

This differs from the » RFC 3986 encoding (see rawurlencode()) in that for historical reasons, spaces are encoded as plus (+) signs.

做个试验

先对字符串abc def进行编码

$str = 'abc def';

echo urlencode($str);

输出结果

abc+def

然后对字符串a=abc+def进行解码

$str = 'a=abc+def';

echo urldecode($str);

输出结果

a=abc def

可以看出确实空格被编码成了+,而+则被解码成空格

怎么解决呢?

那PHP里面有没有使用RFC-3986标准进行编码的呢,有的,是rawurlencode和rawurldecode,PHP官方是这么写的

rawurlencode — URL-encode according to RFC 3986

再来做个试验

先对字符串abc def进行编码

$str = 'abc def';

echo rawurlencode($str);

输出结果

abc%20def

可以看到空格被编码成%20,然后对字符串a=abc+def进行解码

$str = 'a=abc+def';

echo rawurldecode($str);

输出结果

a=abc+def

可以看到+解码后还是+,没有变成空格

结论

所以最符合标准,并且比较容易实现的方案就是让客户端or前端在请求服务端接口时遵循RFC-3986标准进行正确的URL编码

php url传递 加号,坑爹的URL编码-PHP正确处理URL中的加号(+)相关推荐

  1. 关于JAVA中URL传递中文参数,取值是乱码的解决办法

    今天遇到一个问题就是在Action当中把一条中文信息绑定在URL的后面,ActionForward到别一个页面时,用reqeust.getParameter取出是出现乱码的问题. 现解决办法如下: 1 ...

  2. java 中文参数_关于JAVA中URL传递中文参数的问题

    今天在调用一个接口时,需要传递一个中文参数,结果获取不到数据,原因就在于中文传参的编码问题. 问题来源:URL url= new URL("http://XXX?OrganName=司法厅& ...

  3. JS 字符串编码函数(解决URL特殊字符传递问题):escape()、encodeURI()、encodeURIComponent()区别详解

    JS 字符串编码函数(解决URL特殊字符传递问题):escape().encodeURI().encodeURIComponent()区别详解 参考文章: (1)JS 字符串编码函数(解决URL特殊字 ...

  4. 【javaScript】encodeURI来解决URL传递时为什么需要进行两次encodeURI编码

    encodeURI来解决URL传递时为什么需要进行两次encodeURI编码 文章来源于https://blog.csdn.net/u012027337/article/details/5212647 ...

  5. JS 字符串编码函数(解决URL特殊字符传递问题):escape()、encodeURI()、encodeURIComponent()区别详解...

    转:http://www.cnblogs.com/qiantuwuliang/archive/2009/07/19/1526687.html //该方法不会对 ASCII 字母和数字进行编码,也不会对 ...

  6. js符号转码_JS 字符串编码函数(解决URL特殊字符传递问题):escape()、encodeURI()、encodeURIComponent()区别详解...

    转:http://www.cnblogs.com/qiantuwuliang/archive/2009/07/19/1526687.html //该方法不会对 ASCII 字母和数字进行编码,也不会对 ...

  7. ASP.NET页面通过URL传递参数(一)(转载)

    解决的方法一般有3种: 1.设置web.config文件 <system.web>  ......  <globalization requestEncoding="gb2 ...

  8. c#asp.net url 传递中文参数要使用 System.Web.HttpUtility.UrlEncode 而不能使用Server.UrlEncode...

    最近网站里的参数包括中文的例如: http://www.taiba/Tag%b0%ae%c7%e9.html 已开始使用 Server.UrlEncode来做的,但发现,有一些中文在url重写的是说找 ...

  9. url传递中文的解决方案

    作者:xrascal       出处:aspxcn url传递中文的解决方案 1.设置web.config文件.(我不喜欢设置成这样) <system.web> ...... <g ...

最新文章

  1. MVP遇到GMCT:不加入域更改密码有几种方法?
  2. Yii 2 —— Model表前缀
  3. unity android本地推送,Unity安卓本地推送
  4. C#中静态与非静态方法比较
  5. 刚换工作,记录下心得
  6. linux 动态解析,Linux 动态函式库解析[转]Linux -电脑资料
  7. arcgis 统一投影下范围不同_关于Arcgis这62个常用技巧,你造吗
  8. 斯坦福python中文分词stanza
  9. Linux从零开始(二、基础命令(续)解决命令行无限输入,停不下来)
  10. html站点如何命名,html页面的CSS、DIV命名规则
  11. python颜色表_Python+matplotlib绘制不同大小和颜色散点图实例
  12. 10张图,让你瞬间给自己减压
  13. Visual Studio 2019 首个候选发布版发布
  14. vue3中v-model的重大更新
  15. java 我爱你_Java初级教程-课程笔记
  16. 第三篇 层次类非线性表的编程实验 第10章 应用经典二叉树编程
  17. java.lang.NoSuchMethodError: antlr.collections.AST.getLine()I错误时的原因及解决办法
  18. 最常见30种NLP任务练手项目汇总
  19. 遗传算法——matlab实现
  20. 微信H5开发缓存问题解决

热门文章

  1. JAVA分布式架构的演变及解决方案
  2. 如何在SQL Server中使用级联删除?
  3. 如何获取查询生成器以字符串形式输出其原始SQL查询?
  4. wget命令下载文件并另存为不同的文件名
  5. 如何在单元格和循环中使用Microsoft Excel中的正则表达式(Regex)
  6. 如何在MySQL中缩小/清除ibdata1文件
  7. Win11未检测到Logitech Unifying接收器的解决方法
  8. ROS-cmakelists的解释
  9. 浮动元素具有行内块元素特点(HTML、CSS)
  10. PTA—考试座位号(C语言)