WebView应用下载编码文件存为index.php而非原扩展名文件的问题求助
解决WebView下载动态URL文件时保存为index.php的问题
问题核心在于URLUtil.guessFileName()会优先从URL路径提取文件名,而动态PHP接口的URL路径是index.php,导致默认文件名错误。浏览器能正确识别是因为它会优先解析HTTP响应头中的Content-Disposition字段,我们需要手动实现这个逻辑。
解决方案步骤
1. 手动解析Content-Disposition头提取文件名
服务器返回文件时,通常会在Content-Disposition响应头中携带正确文件名(比如attachment; filename="document.pdf"或编码格式的attachment; filename*=UTF-8''document.pdf)。编写工具方法解析这个字段:
private String getFileNameFromContentDisposition(String contentDisposition) { if (contentDisposition == null || contentDisposition.trim().isEmpty()) { return null; } String fileName = null; // 先处理RFC 5987标准的编码文件名格式(filename*=UTF-8''xxx) Pattern encodedPattern = Pattern.compile("filename\\*=UTF-8''([^;]+)"); Matcher encodedMatcher = encodedPattern.matcher(contentDisposition); if (encodedMatcher.find()) { try { fileName = URLDecoder.decode(encodedMatcher.group(1), "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } // 若未找到编码格式,处理常规filename格式(filename="xxx" 或 filename=xxx) if (fileName == null) { Pattern plainPattern = Pattern.compile("filename=\"?([^\"]*)\"?"); Matcher plainMatcher = plainPattern.matcher(contentDisposition); if (plainMatcher.find()) { fileName = plainMatcher.group(1); } } return fileName; }
2. 在WebView下载回调中优先使用解析出的文件名
在WebView.DownloadListener的onDownloadStart方法中,先尝试从contentDisposition提取文件名,失败后再用URLUtil.guessFileName()兜底:
webView.setDownloadListener(new WebView.DownloadListener() { @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) { // 优先从Content-Disposition提取文件名 String fileName = getFileNameFromContentDisposition(contentDisposition); // 兜底逻辑:如果提取失败,再用URLUtil的默认方法 if (fileName == null || fileName.trim().isEmpty()) { fileName = URLUtil.guessFileName(url, contentDisposition, mimeType); } // 执行后续下载逻辑(示例:调用系统下载管理器) DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setMimeType(mimeType); request.addRequestHeader("User-Agent", userAgent); request.setDescription("正在下载文件..."); request.setTitle(fileName); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); downloadManager.enqueue(request); } });
关键注意事项
- 确认服务器返回的
Content-Disposition头正确:可通过Chrome开发者工具的Network面板,查看下载请求的响应头是否包含该字段及正确文件名。 - 处理文件名编码:工具方法已兼容UTF-8编码的
filename*格式,避免中文或特殊字符文件名乱码。
内容的提问来源于stack exchange,提问作者Noman
相关产品推荐
相关产品推荐

