[转帖] 传参base64时的+号变空格问题
https://www.cnblogs.com/codelogs/p/17255425.html
原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明。
问题发生#
上上周,看到一位老哥找我们组同事联调接口,不知道是什么问题,两人坐一起搞了快1个小时,看起来好像有点复杂。
突然,老哥发出一声卧槽,"我传参里的+号,到你这怎么变成了空格!",这个声音很大,我明显的听到了,很快,我就大概Get到了他们的问题点。
我猜测他们遇到的问题大概如下:
- 我们的接口协议上,都会将请求数据做一次base64编码,然后放到data参数上。
- 然后某些数据做base64编码后有
+,如{"notes":"代码"}base64编码为eyJub3RlcyI6IuS7o+eggSJ9Cg==。 - 然后直接拼到data参数上,即
data=eyJub3RlcyI6IuS7o+eggSJ9Cg==,组织成http请求发出。
如果写成等价的curl,就是这样:
$ curl http://localhost:8080/send -d 'data=eyJub3RlcyI6IuS7o+eggSJ9Cg=='
写个测试接口调试下看看,如下:
这就是他们遇到的问题,+会变成空格,这个坑其实蛮容易踩到,我自己刚工作时就踩到过这个坑,也多次看到或听到别人同踩此坑
问题原因#
这个问题和urlencode编码有关,urlencode编码,一般来说,除字母、数字和*,.,-和_这些字节原样输出外,其它字节都会编码为%XX(16进制)的形式。
但有一个特例,如下:
String enc = URLEncoder.encode(" ", "UTF-8");
System.out.println(enc); // 输出+号
String dec = URLDecoder.decode("+", "UTF-8");
System.out.println(dec); // 输出空格
特例就是空格会被编码为+号,反之,+号会被解码为空格!
注:在新的RFC 2396规范中,空格其实也可以编码成%20,而解码时,
+号与%20都会被解码为空格。
回想上面的场景,如果将带有+号的base64字符串,原封不动的封装到data=中,再发送给Tomcat等Web服务器,若Tomcat侧做一次urldecode解码,+是不是就变成空格了
而Tomcat确实会做urldecode解码这样的操作,当调用方的Content-Type为application/x-www-form-urlencoded时,这里知道有这种操作即可,想了解细节可看看我写的这篇文章 由x-www-form-urlencoded引发的接口对接失败
解决问题#
解决这种问题,主要有两种方法,如下:
- 调用方对参数做urlencode编码。
按规范来看,当Content-Type为application/x-www-form-urlencoded时,调用方是必须对参数名与参数值做urlencode的,java实现如下:
String base64Str = Base64.getEncoder().encodeToString(data);
String requestStr = "data=" + URLEncoder.encode(base64Str, "UTF-8");
这里做了urlencode后,+会被编码为%2B,再由服务端解码,就会变成原样的+号。
注:如果是使用apache的HttpClient,可考虑使用
UrlEncodedFormEntity,它会自动做这个事情。
- 使用urlsafe版本的base64。
普通的base64不能直接作为参数值,因为它可能包含+、/这两个url不安全的字符,所以base64有个变种叫urlBase64,它将+、/替换成了url安全的-、_,java实现如下:
String urlBase64Str = Base64.getUrlEncoder().encodeToString(data);
String requestStr = "data=" + urlBase64Str;
关于base64、urlencode编码,之前也专门写过一篇文章,感兴趣可进一步阅读 hex,base64,urlencode编码方案对比
作者:打码日记
出处:https://www.cnblogs.com/codelogs/p/17255425.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
[转帖] 传参base64时的+号变空格问题的更多相关文章
- 传参base64时的+号变空格问题
原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明. 问题发生 上上周,看到一位老哥找我们组同事联调接口,不知道是什么问题,两人坐一起搞了快1个小时,看起来好像有点复 ...
- base64码通过http传输 +号变 空格 问题解决
通过七牛云base64上传图片,通过官方示例上传成功后,根据示例改了一个controller. 通过前端往后端传base64码形式进行测试.死活不通过,七牛报400. 仔细排查后发现,示例转换的bas ...
- base64码通过http传输 +号变 空格 以及 图片编码后字符串较长导致POST提交失败 问题解决
场景:图片上传OSS存储,接口拿字符串去接前端传的base64码,服务器打印入参传的值,发现和前端打印的值有所区别,服务器中打印的值所有+号全部变成空格. 解决办法: Java中使用:url = ur ...
- js中给函数传参函数时,函数加括号与不加括号的区别
<!doctype html><html><head><script> function show() { alert("123") ...
- 浏览器url传参中文时得到null的解决方法
在写一个中文参数需求的时候遇到了以下问题,经过半天的测试和各种编码,以及网上一些有用没用的资料尝试终于解决 比如下面的url地址:http://travel.widget.baike.com:8 ...
- tomcat自动URLDecode解码问题(+号变空格)
最近项目中出现一个问题,就是前段调后端接口,参数带+号,传到后端后+号自动URLDecode成空格了. 1.问题排查 条件:tomcat配置server.xml有URIEncoding="U ...
- 对于querystring取值时候发生+号变空格的问题
今天遇到这个问题,在网上找了几个答案,解决了问题,很高兴,所以贴出来给大家分享一下: URL如下 http://127.0.0.1/test/test.aspx?sql= and id='300+' ...
- Spring cloud Feign不支持对象传参解决办法[完美解决]
spring cloud 使用 Feign 进行服务调用时,不支持对象参数. 通常解决方法是,要么把对象每一个参数平行展开,并使用 @RequestParam 标识出每一个参数,要么用 @Reques ...
- restTemplate getForObject中map传参问题
在使用restTemplate中getForObject的map传参形式时: 开始时我是这么调用的: RestTemplate rest = new RestTemplate(); Map<St ...
- 悉数 Python 函数传参的语法糖
TIOBE排行榜是程序开发语言的流行使用程度的有效指标,对世界范围内开发语言的走势具有重要参考意义.随着数据挖掘.机器学习和人工智能相关概念的风行,Python一举收获2018年年度语言,这也是Pyt ...
随机推荐
- 深入理解JavaScript堆栈、事件循环、执行上下文和作用域以及闭包
1. 堆栈 在JavaScript中,内存堆是内存分配的地方,调用栈是代码执行的地方. 原始类型的保存方式:在变量中保存的是值本身,所以原始类型也被称之为值类型. 对象类型的保存方式:在变量中保存的是 ...
- vivo 海量微服务架构最新实践
作者:来自 vivo 互联网中间件团队 本文根据罗亮老师在"2023 vivo开发者大会"现场演讲内容整理而成.公众号回复[2023 VDC]获取互联网技术分会场议题相关资料. v ...
- AnimatedList 实现动态列表
AnimatedList实现动画 AnimatedList 和 ListView 的功能大体相似,不同的是, AnimatedList 可以在列表中插入或删除节点 时执行一个动画,在需要添加或删除列 ...
- 【昇腾】ModelArts与Atlas 200 DK云端协同开发——行人检测Demo(完整版)
摘要:本文主要为大家展示如何基于ModelArts与Atlas 200 DK 端云协同开发的行人检测Demo实现过程. 基于开源数据集,使用ModelArts训练行人检测模型,在本地MindStudi ...
- 开发老人笔记:Git 常用命令清单
摘要:git是目前世界上最先进的分布式版本控制系统. 多人协作 master:此分支用来发布稳定的代码,合并一般是由管理员合并 dev:此分支用于团队开发,团队成员向此分支提交代码 bug:此分支用于 ...
- 先收藏!关于Java类、接口、枚举的知识点大汇总
摘要:Java知识点精选之类.接口.枚举30问,算是比较基础的,希望大家一起学习进步. 整理了一些JAVA语言的在类.接口.枚举等方面的知识点以及大家常遇到的问题.希望能帮助到大家. Q: 各修饰符所 ...
- 学会这5种JS函数继承方式,前端面试你至少成功50%
摘要:函数继承是在JS里比较基础也是比较重要的一部分,而且也是面试中常常要问到的.下面带你快速了解JS中有哪几种是经常出现且必须掌握的继承方式.掌握下面的内容面试也差不多没问题啦~ 本文分享自华为云社 ...
- 边缘AI方案落地问题探讨
摘要:本文介绍了如何兑现边缘AI带来好处的承诺,并针对边缘AI落地和商业闭环发起的开源社区工作. 本文分享自华为云社区<华为云:边缘AI方案落地问题探讨及调研>,作者: 华为云边缘云创新实 ...
- Solon2 开发之IoC,五、Bean 扫描的三种方式
1.启动时扫描 package org.example.demo; public class DemoApp{ public static void main(String[] args){ // / ...
- 使用Expression代替反射读取IDataReader或IDataRecord给实体类赋值
ExpressionMapper代码 using System; using System.Collections.Concurrent; using System.Collections.Gener ...