跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Web GET 请求参数中 URLEncoder 编码问题与解决方案

综述由AI生成Web GET 请求中特殊字符(如+、/、=)被篡改的问题,特别是 Base64 密文传输时“+”会被解析为空格的原因。通过对比 URL 编码规则,指出需使用 URLEncoder 进行标准编码。提供了 Java 工具类示例及 SpringBoot 后端接收参数的自动解码机制,并强调了字符集统一和避免重复编码的注意事项,确保参数传输准确无误。

云朵棉花糖发布于 2026/3/22更新于 2026/5/2427 浏览

前言

问题场景:后端生成并返回给前端的字符串中有'+',但是前端通过 GET 请求将该参数传入后端后,'+'被替换成了' '。

一、'+'为什么被替换

GET 请求中遇到 + 被替换为空格的核心原因是:+ 是 URL 编码中的特殊字符(代表空格),当包含 + 的字符串直接作为 GET 参数传输时,浏览器/HTTP 客户端会自动将 + 解析为空格,服务器接收时就会出现替换问题——这是 URL 编码规范(RFC 3986)和 HTTP 传输的固有特性,并非代码错误,而是参数传输格式不符合规范导致的。

1.1 URL 编码(Percent-Encoding)的核心规则

URL 只能包含「字母、数字、- _ . ~」等安全字符,其他字符(如 /、+、=、& 等)属于「保留字符」或「不安全字符」,必须通过 %+十六进制 ASCII 码 编码后传输:

空格的 URL 编码是 %20,但早期为了简化,也常用 + 表示空格(这是 application/x-www-form-urlencoded 格式的约定);+ 本身的 ASCII 码是 43,对应的 URL 编码是 %2B

1.2 GET 请求中 + 被替换为空格的完整流程

原始字符串:...ec+khJ1Qh...
↓ 浏览器/HTTP 客户端(如 OkHttp、HttpClient)自动解析
识别 `+` 为 URL 中的「空格占位符」
↓ 传输到服务器
服务器接收参数时,将 `+` 解码为空格 → ...ec khJ1Qh...

1.3 为什么 Base64 密文容易出现这个问题?

当传输的参数是 Base64 编码的密文,而 Base64 编码的字符集包含 +、/、= 三个特殊字符:

+:对应 URL 中的空格; /:URL 中的路径分隔符; =:URL 参数中的键值对分隔符; 这三个字符直接放在 GET 参数中都会被篡改,其中 + 是最容易触发的问题。

二、怎么处理

2.1 使用 URL 安全编码

使用 JDK 自带 java.net.URLEncoder 类,可直接实现标准 URL 编码(注意字符集必须用 UTF-8),通过 URLEncoder.encode(content, StandardCharsets.UTF_8); 进行编码

代码如下(示例):

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * URL 编码工具类(标准 URLEncode)
 */
public class UrlEncodeUtil {
    /**
     * 标准 URL 编码(适配 GET 参数)
     * @param content 待编码内容(如 Base64 密文)
     * @return 编码后的字符串
     */
    public static String encode(String content) {
        if (content == null || content.trim().isEmpty()) {
            return "";
        }
        // 关键:字符集必须用 UTF-8,且编码空格为 %20(而非 +)
        return URLEncoder.encode(content, StandardCharsets.UTF_8);
    }

    /**
     * 标准 URL 解码(后端接收参数时 SpringBoot 自动解码,此方法仅备用)
     * @param encodedContent 编码后的字符串
     * @return 原始内容
     */
    public static String decode(String encodedContent) {
        if (encodedContent == null || encodedContent.trim().isEmpty()) {
            return "";
        }
        try {
            return java.net.URLDecoder.decode(encodedContent, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("URL 解码失败", e);
        }
    }
}

2.2 生成的 URL 示例(编码前后对比)

处理阶段内容示例
原始令牌(Base64)954nFKV42Ox7K0qCdd/oE2wj3hJ4B/51I0IHSFWDHgztgBqxOE0ec+khJ1QhOEAP…
URL 编码后954nFKV42Ox7K0qCdd%2FoE2wj3hJ4B%2F51I0IHSFWDHgztgBqxOE0ec%2BkhJ1QhOEAP…

可以看到:

  • 被编码为 %2B; / 被编码为 %2F; =(若有)被编码为 %3D; 这些编码后的字符在 GET 请求传输中不会被篡改,服务器接收后会自动还原。

2.3 后端 Get 接收参数自动解码

请求发送到后端时,SpringBoot 会自动对 @RequestParam 注解的参数做 URL 解码,无需手动处理:

@GetMapping("/reset-password")
public String showResetPage(@RequestParam String token) {
    // token 已经是 URL 解码后的原始 Base64 令牌(+、/ 已还原)
    System.out.println("接收的令牌(已解码):" + token);
    // 后续验证令牌、展示重置页面...
    return "reset-password";
}

2.4 注意事项

  • 字符集必须统一:编码和解码都必须使用 UTF-8,否则会出现乱码(URLEncoder.encode 若不指定字符集,JDK 8 及以上默认 UTF-8,但建议显式指定)。
  • 避免重复编码:不要对已编码的 URL 再次编码(如 encode(encode(token))),否则会导致 %2B 被编码为 %252B,服务器解码后得到 %2B 而非 +。
  • 特殊字符全覆盖:除了 +,Base64 中的 /、= 也会被 URL 解析器处理,标准 URLEncode 会一次性处理所有特殊字符,无需单独替换。
  • URL 长度限制:GET 请求的 URL 有长度限制(不同浏览器/服务器约 2048 字符),若你的令牌过长(如 512 位),建议:优先使用 POST 请求传输令牌;或缩短令牌长度(如优化加密内容)。

总结

在使用 GET 请求传递参数时,+、/、= 如果不进行 URLEncode 进行编码,服务器会将该字符进行篡改,导致后端接收的参数与实际值出现偏差。

目录

  1. 前言
  2. 一、“+”为什么被替换
  3. 1.1 URL 编码(Percent-Encoding)的核心规则
  4. 1.2 GET 请求中 + 被替换为空格的完整流程
  5. 1.3 为什么 Base64 密文容易出现这个问题?
  6. 二、怎么处理
  7. 2.1 使用 URL 安全编码
  8. 2.2 生成的 URL 示例(编码前后对比)
  9. 2.3 后端 Get 接收参数自动解码
  10. 2.4 注意事项
  11. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 轻量级 SVGA 动画播放器:Web 端流畅动画实现
  • Python 异步爬虫结合 K8S 弹性伸缩构建高并发采集系统
  • Vue 3 前端调试实战与开发技巧
  • 树莓派 5 结合 Whisper 与 EdgeTTS 构建全离线语音助手
  • OpenClaw:开源 AI 智能体框架的技术解析与实战部署
  • 从零构建可扩展 Flutter 应用:v1.0 到 v2.0 全代码详解
  • 微信集成 Qclaw AI 智能体:零门槛操作指南
  • 阿里健康医药 B2B 团队敏捷转型实践
  • Linux C++ 多线程编程入门:从核心概念到常用函数详解
  • Elasticsearch 核心概念与 Java 客户端实战指南
  • C++ 继承机制详解:派生类函数、虚继承与菱形继承案例
  • 如何在 Ubuntu 20.04 或 22.04 上安装 Python 3
  • Web-Rooter:基于 IR + Lint 的 AI Agent 联网执行方案
  • 使用 DeepFace 与 OpenCV 实现实时情绪分析器
  • 微调 Llama3 改变大模型自我认知,单卡即可训练
  • 课程论文写作痛点解析与 AI 辅助策略
  • 多卡部署 Qwen3-VL-32B:vLLM 通信瓶颈与 llama.cpp 实践
  • ChatTTS WebUI 使用指南:轻松制作拟真语音
  • 脉向AI|当豆包手机遭遇“全网封杀“:GUI Agent是通向AGI的必经之路吗?
  • Linux 进程间通信进阶:管道与共享内存详解

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online