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
相关产品推荐
相关产品推荐

