前端请求参数中的加号去到后端(nodejs)变成空格的问题

问题来源

最近碰到一个很奇怪的问题,js进行网络请求的时候,只要带上+符号,nodejs(express框架)中的req.query.key的值里面的+号就会莫名其妙地变成空格。比如,
前端: $.get('/test?' + 'key=' + 'i am a + char');
后端: req.query.key === 'i am a char'.
然后我就想到,可能是编码问题。果断将前端的key参数进行编码encodeURIComponent(key),然后发现一切都正常了。

故事进展

但是我还是蛮困惑的。前端在不编码的情况下,为什么空格能正常传值,而加号就不行?我在网上搜了好久,依然没有一个让我感到满意的答案。很多人说直接全局替换加号为%2B就好啦(加号的编码)。其实不用替换这么麻烦,直接对整个字符串进行一次编码(encodeURIComponent(key))就可以啦,自然而然就会替换成%2B了。

继续深入

然后,我断点调试了一下express,惊奇地发现req.url里面的值居然显示有加号:req.url === xxx?key=i%20am%20a%20+%20char。也就是说,其实,加号已经传过来了!!!只是express把它转化成空格放在req.query而已!!!为什么要这么做呢!!!

跟踪代码

为了进一步地了解发生了什么事,于是我开启debug模式。惊奇地发现代码如下

exports.decode = function (str) {   
  try {        
    return decodeURIComponent(str.replace(/\+/g, ' '));    
  } catch (e) {        
    return str;    
  }
};

还得多一句:为啥?为啥express要这么做?初初我以为这可能是express的bug,毕竟加号已经传过来了。但是现在我已经抛开这个想法了,人家是有意这么搞的。那也就是说,只要我修改这些代码,express是可以正常接收前端未经编码的参数值。

思考

  • 我比较好奇这是一种怎样的机制。在不编码的情况下,为什么后端接收的空格变成编码后的%20,而加号会直接传过来了?
  • express团队为什么会将加号全局替换掉?为了安全着想?还是说,这是一种规范,大家得遵守?

最后的最后

当然是加号变成空格的解决方法啦

  • 每个参数进行编码
  • 貌似只有上面这种方案比较好(直接改express源码不太好吧)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容