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

Selenium Java访问blob协议PDF报unknown protocol异常如何解决

问题根因

java.net.MalformedURLException: unknown protocol: blob 触发的核心原因是Java标准URL类默认不识别blob协议:blob是浏览器端生成的伪URL,仅作为浏览器内存/会话存储中二进制对象的引用标记,不是可通过Java网络栈直接发起请求的标准化资源路径。如果直接把blob地址传入driver.get()、或者用Java原生URL类尝试读取blob地址,就会抛出该异常。
另外blob地址和创建它的页面上下文强绑定,页面刷新、文档卸载后blob地址会自动失效,也会间接触发资源访问异常。

排查步骤
  • 定位异常触发点:查看报错栈,确认异常是调用driver.get(blobUrl)时触发,还是自定义逻辑里写了new URL(blobPath)做资源读取时触发,区分是Selenium调用逻辑问题还是自定义URL处理逻辑问题
  • 校验blob地址有效性:在浏览器控制台手动执行window.open(你的blob地址),确认可以正常打开PDF,排除地址过期、资源被浏览器回收的情况
  • 核对Selenium与浏览器驱动版本:低于3.141.59的旧版Selenium对前端二进制资源交互支持存在已知缺陷,先升级到稳定兼容版本排除版本问题
解决方案

方案1:通过JS触发浏览器侧操作,避免Java直接解析blob地址

不要把blob地址传给Java侧的URL解析逻辑,直接通过Selenium执行JS脚本,让浏览器自身处理blob资源的跳转或下载:

String blobUrl = "blob:https://your-domain.com/xxxx-xxxx-xxxx";
// 场景1:需要下载PDF
String downloadJs = "const link = document.createElement('a');" +
                    "link.href = arguments[0];" +
                    "link.download = 'test.pdf';" +
                    "document.body.append(link);" +
                    "link.click();" +
                    "link.remove();";
((JavascriptExecutor)driver).executeScript(downloadJs, blobUrl);

// 场景2:需要在当前页预览PDF
((JavascriptExecutor)driver).executeScript("window.location.href = arguments[0]", blobUrl);

如果使用Chrome浏览器,提前配置浏览器选项避免内置PDF预览器拦截逻辑:

ChromeOptions options = new ChromeOptions();
HashMap<String, Object> prefs = new HashMap<>();
prefs.put("plugins.always_open_pdf_externally", false);
prefs.put("profile.default_content_settings.popups", 0);
options.setExperimentalOption("prefs", prefs);
WebDriver driver = new ChromeDriver(options);

方案2:需读取PDF内容做校验时,在浏览器端转base64回传Java

如果需要获取PDF二进制内容做断言、存储等操作,不要通过Java网络请求拉取blob,通过JS在浏览器侧将blob转换为base64字符串后回传,Java侧解码即可拿到原始字节:

// 异步执行JS读取blob转base64
String readBlobJs = "const blobUrl = arguments[0];" +
                    "const callback = arguments[1];" +
                    "fetch(blobUrl).then(res => res.blob()).then(blob => {" +
                    "  const reader = new FileReader();" +
                    "  reader.onloadend = () => callback(reader.result);" +
                    "  reader.readAsDataURL(blob);" +
                    "});";
String base64Content = (String) ((JavascriptExecutor)driver).executeAsyncScript(readBlobJs, blobUrl);
// 去除base64头信息 解码为PDF字节数组
byte[] pdfBytes = Base64.getDecoder().decode(base64Content.split(",")[1]);
// 后续可直接对字节数组做内容断言、本地存储等操作

方案3:自定义Java blob协议处理器(不推荐)

如果业务场景强制要求用Java原生URL类处理blob地址,可以自行实现URLStreamHandler注册blob协议,但该方案需要打通Java进程和浏览器内存的资源读取链路,实现成本极高,仅适合极端特殊场景适配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:58:00