https://www.cnblogs.com/codelogs/p/17255425.html

原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明。

问题发生#

上上周,看到一位老哥找我们组同事联调接口,不知道是什么问题,两人坐一起搞了快1个小时,看起来好像有点复杂。

突然,老哥发出一声卧槽,"我传参里的+号,到你这怎么变成了空格!",这个声音很大,我明显的听到了,很快,我就大概Get到了他们的问题点。

我猜测他们遇到的问题大概如下:

  1. 我们的接口协议上,都会将请求数据做一次base64编码,然后放到data参数上。
  2. 然后某些数据做base64编码后有+,如{"notes":"代码"}base64编码为eyJub3RlcyI6IuS7o+eggSJ9Cg==
  3. 然后直接拼到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引发的接口对接失败

解决问题#

解决这种问题,主要有两种方法,如下:

  1. 调用方对参数做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,它会自动做这个事情。

  1. 使用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时的+号变空格问题的更多相关文章

  1. 传参base64时的+号变空格问题

    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明. 问题发生 上上周,看到一位老哥找我们组同事联调接口,不知道是什么问题,两人坐一起搞了快1个小时,看起来好像有点复 ...

  2. base64码通过http传输 +号变 空格 问题解决

    通过七牛云base64上传图片,通过官方示例上传成功后,根据示例改了一个controller. 通过前端往后端传base64码形式进行测试.死活不通过,七牛报400. 仔细排查后发现,示例转换的bas ...

  3. base64码通过http传输 +号变 空格 以及 图片编码后字符串较长导致POST提交失败 问题解决

    场景:图片上传OSS存储,接口拿字符串去接前端传的base64码,服务器打印入参传的值,发现和前端打印的值有所区别,服务器中打印的值所有+号全部变成空格. 解决办法: Java中使用:url = ur ...

  4. js中给函数传参函数时,函数加括号与不加括号的区别

    <!doctype html><html><head><script> function show() { alert("123") ...

  5. 浏览器url传参中文时得到null的解决方法

    在写一个中文参数需求的时候遇到了以下问题,经过半天的测试和各种编码,以及网上一些有用没用的资料尝试终于解决    比如下面的url地址:http://travel.widget.baike.com:8 ...

  6. tomcat自动URLDecode解码问题(+号变空格)

    最近项目中出现一个问题,就是前段调后端接口,参数带+号,传到后端后+号自动URLDecode成空格了. 1.问题排查 条件:tomcat配置server.xml有URIEncoding="U ...

  7. 对于querystring取值时候发生+号变空格的问题

    今天遇到这个问题,在网上找了几个答案,解决了问题,很高兴,所以贴出来给大家分享一下: URL如下 http://127.0.0.1/test/test.aspx?sql= and id='300+' ...

  8. Spring cloud Feign不支持对象传参解决办法[完美解决]

    spring cloud 使用 Feign 进行服务调用时,不支持对象参数. 通常解决方法是,要么把对象每一个参数平行展开,并使用 @RequestParam 标识出每一个参数,要么用 @Reques ...

  9. restTemplate getForObject中map传参问题

    在使用restTemplate中getForObject的map传参形式时: 开始时我是这么调用的: RestTemplate rest = new RestTemplate(); Map<St ...

  10. 悉数 Python 函数传参的语法糖

    TIOBE排行榜是程序开发语言的流行使用程度的有效指标,对世界范围内开发语言的走势具有重要参考意义.随着数据挖掘.机器学习和人工智能相关概念的风行,Python一举收获2018年年度语言,这也是Pyt ...

随机推荐

  1. Java数组中常见的方法

    一.前言 代码: //给定一个数组 int[] arr = {234,312,32,1321,321,43}; int[] arr1 = new int[6]; int[] arr2 = {1,3,7 ...

  2. 神经网络入门篇:直观理解反向传播(Backpropagation intuition)

    详细推导反向传播 下图是逻辑回归的推导: 回想一下逻辑回归的公式(参考公式1.2.公式1.5.公式1.6.公式1.15) 公式1.38: \[\left. \begin{array}{l} {x }\ ...

  3. 手把手带你写Node.JS版本小游戏

    摘要:今天就利用Node.JS为大家带来简单有趣的的剪刀石头布的小游戏. JavaScript的出现催动了前端开发的萌芽,前后端分离促进了Vue.React等开发框架的发展,Weex.React-Na ...

  4. 华为云媒体査勇:华为云在视频AI转码领域的技术实践

    摘要:为大家介绍华为云媒体处理服务在视频AI转码领域的一些技术实践. 随着5G的落地和消费终端的不断升级,消费环节对视频画质的要求也越来越高,为了给消费者带来更清晰.更逼真和更具沉浸感的观感体验,对云 ...

  5. VEGA:诺亚AutoML高性能开源算法集简介

    摘要:VEGA是华为诺亚方舟实验室自研的全流程AutoML算法集合,提供架构搜索.超参优化.数据增强.模型压缩等全流程机器学习自动化基础能力. 本文分享自华为云社区<VEGA:诺亚AutoML高 ...

  6. 没有苹果开发者账号能否创建ios证书-最新

    ​ 摘要: 本文介绍了在没有Mac电脑的情况下,使用appuploader工具生成iOS证书和描述文件的方法.随着大前端和H5框架的热门话题,越来越多的人希望将H5应用打包成iOS应用.苹果官方提供的 ...

  7. Docker 安装 ELK,EFK代替

    ELK 版本因为 前面 Elasticsearch 用的 7.9.3 版本,所以 kibana-7.9.3.logstash-7.9.3 都用 7.9.3 版本 安装配置 Elasticsearch ...

  8. 【Django-Vue】手机号是否存在接口 多方式登录接口 腾讯云短信介绍和申请 api与sdk

    目录 昨日回顾 今日内容 0 登录注册功能设计 1 短信登录接口 视图类 2 多方式密码登录接口 视图类 序列化类 路由 3 腾讯云短信介绍和申请 3.1api与sdk 补充 练习 昨日回顾 # 你的 ...

  9. 2021InfoComm|钉钉会议 Rooms 的 "全场景" 智能化解决方案

    InfoComm China 是亚太地区规模盛大的专业视听和集成体验解决方案商贸展会,提供前沿革新的产品和一系列高价值的技术展示. 在疫情期间,钉钉音视频支持了全国人民在线办公.在家上课,单日在线会议 ...

  10. C# 实用第三方库

    C# 实用第三方库 Autofac 依赖注入IOC框架 NuGet安装:Autofac.Autofac.Extras.DynamicProxy AutoMapper 对象映射 Mapster 对象映射 ...