欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-03 23:19:56
...

问题来源

最近碰到一个很奇怪的问题,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源码不太好吧)