You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTML文件上传至Java REST服务解码失败问题求助

解决Base64解码失败(Illegal base64 character 20)的问题

你遇到的java.lang.IllegalArgumentException: Illegal base64 character 20是因为base64字符串里混入了空格(ASCII码20)。问题根源在于你通过URL参数传递base64数据时,没有对其进行URL编码——base64中的+号会被浏览器自动替换为空格,导致服务端收到的base64串无效,解码失败。

下面提供两种解决方案,其中第二种是更标准的文件上传方式,推荐优先使用:

方案一:修复Base64 URL传输问题

客户端代码修改

在发送Ajax请求时,对file_content也执行encodeURIComponent编码,确保base64中的特殊字符(比如+、/)不会被URL自动转义:

var file = document.getElementById('add_attach').files[0];
var filename = document.getElementById('add_attach').value;
if (file) {
    var reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function(e) {
        var name = encodeURIComponent(filename);
        // 对base64内容也进行URL编码,避免特殊字符被转义
        var file_content = encodeURIComponent(e.target.result);
        // 构造请求URL(这里用XMLHttpRequest为例,你可以替换成常用的Ajax库)
        var xhr = new XMLHttpRequest();
        xhr.open('GET', `/your-api-url?filename=${name}&content=${file_content}`, true);
        xhr.onload = function() {
            if (xhr.status === 200) {
                console.log('文件上传处理成功');
            } else {
                console.error('请求失败');
            }
        };
        xhr.send();
    };
}

服务端代码修改

先对收到的file_content进行URL解码,再处理base64部分:

// 假设你通过请求参数获取file_content
String file_content = request.getParameter("content");
// 先URL解码,还原被转义的特殊字符
String decodedContent = java.net.URLDecoder.decode(file_content, StandardCharsets.UTF_8.name());
// 截取base64数据部分
int base64Index = decodedContent.indexOf("base64,") + 7;
String base64Data = decodedContent.substring(base64Index);
// 解码base64
byte[] decodedBytes = Base64.getDecoder().decode(base64Data);
// 后续处理逻辑...

方案二:使用FormData直接上传文件(推荐)

通过URL传base64不仅会让文件体积增大30%左右,还受限于URL长度限制(大文件根本无法传输)。更标准的做法是用FormData直接上传原始文件,无需转base64:

客户端代码修改

var file = document.getElementById('add_attach').files[0];
var filename = document.getElementById('add_attach').value;
if (file) {
    var formData = new FormData();
    formData.append('file', file);
    // 可选:传递自定义文件名
    formData.append('filename', filename);
    
    var xhr = new XMLHttpRequest();
    xhr.open('POST', `/your-api-url`, true);
    xhr.onload = function() {
        if (xhr.status === 200) {
            console.log('文件上传处理成功');
        } else {
            console.error('请求失败');
        }
    };
    xhr.send(formData);
}

服务端代码修改(以Spring MVC为例)

直接接收MultipartFile即可,无需手动处理base64:

@PostMapping("/your-api-url")
public ResponseEntity<String> handleFileUpload(
    @RequestParam("file") MultipartFile file,
    @RequestParam(required = false) String filename
) {
    try {
        // 获取文件字节数组
        byte[] fileBytes = file.getBytes();
        // 使用自定义文件名或文件原始名
        String actualFilename = filename != null ? filename : file.getOriginalFilename();
        // 后续处理逻辑(比如保存文件、解析内容等)
        return ResponseEntity.ok("文件处理完成:" + actualFilename);
    } catch (Exception e) {
        e.printStackTrace();
        return ResponseEntity.badRequest().body("文件处理失败:" + e.getMessage());
    }
}

方案二更符合HTTP文件上传的标准规范,避免了base64编码的额外开销和URL长度限制问题,强烈推荐使用。如果因为特殊场景必须用base64传输,一定要记得对base64内容做URL编码,服务端再解码处理。

内容的提问来源于stack exchange,提问作者Arno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:24:34