如何隐藏HTML页面中源返回XML错误(BlobNotFound)的所有iframe?
解决iframe加载PDF时批量隐藏错误iframe的问题
我用<iframe>展示PDF预览时遇到问题:页面里多个<iframe>用来显示PDF,但有时候源URL对应的PDF不存在,<iframe>会返回含BlobNotFound的XML错误,我想隐藏这类出错的<iframe>。
单个指定ID的<iframe>检查代码能正常工作,但改成批量检查所有<iframe>时,会错误隐藏所有<iframe>,哪怕没出错的也被隐藏了。
原尝试代码
单个ID的有效代码
<script> const myIframe = document.getElementById('myFrame1'); fetch('example.xml') .then(response => { if (!response.ok) { throw new Error('XML file not found'); } return response.text(); }) .then(xmlString => { const parser = new DOMParser(); const xmlDoc = parser.parseFromString(xmlString, "text/xml"); // check for errors in the XML content const error = xmlDoc.getElementsByTagName("parsererror"); if (error.length > 0) { myIframe.style.display = 'none'; // hide the iframe if there is an error } }) .catch(error => { console.error(error); myIframe.style.display = 'none'; // hide the iframe if there is an error }); </script>
批量检查的错误代码
<script> const iframes = document.getElementsByTagName('iframe'); for (let i = 0; i < iframes.length; i++) { const iframe = iframes[i]; fetch(iframe.src) .then(response => { if (!response.ok) { throw new Error('XML file not found'); } return response.text(); }) .then(xmlString => { const parser = new DOMParser(); const xmlDoc = parser.parseFromString(xmlString, "text/xml"); // check for errors in the XML content const error = xmlDoc.getElementsByTagName("parsererror"); if (error.length > 0) { iframe.style.display = 'none'; // hide the iframe if there is an error } }) .catch(error => { console.error(error); iframe.style.display = 'none'; // hide the iframe if there is an error }); } </script>
错误XML示例
<?xml version="1.0" encoding="utf-8"?> <Error> <Code>BlobNotFound</Code> <Message> The specified blob does not exist. RequestId:xxxxxxxx Time:timestamp </Message> </Error>
问题分析
批量代码出错的核心原因:
- 跨域限制:如果PDF源URL与当前页面不同域,
fetch会因浏览器跨域策略失败,直接进入catch块隐藏所有iframe。 - 错误判断逻辑不匹配:原代码用
parsererror标签判断错误,但实际返回的XML错误结构是<Error>下的<Code>BlobNotFound</Code>,判断条件完全不对应。
修正后的批量检查代码
<script> // 可根据实际场景调整选择器,比如只选择class为pdf-preview的iframe const iframes = document.querySelectorAll('iframe'); iframes.forEach(async (iframe) => { try { const response = await fetch(iframe.src, { mode: 'no-cors' // 避免跨域请求直接报错 }); // 同域下可正常解析响应内容 if (response.type !== 'opaque') { const xmlString = await response.text(); const parser = new DOMParser(); const xmlDoc = parser.parseFromString(xmlString, "text/xml"); // 精准匹配BlobNotFound错误 const errorCode = xmlDoc.querySelector('Error > Code'); if (errorCode?.textContent.trim() === 'BlobNotFound') { iframe.style.display = 'none'; } } } catch (error) { // 跨域时通过iframe的error事件监听加载失败 iframe.addEventListener('error', () => { // 若业务中跨域加载失败均为PDF不存在,可取消注释下面的代码 // iframe.style.display = 'none'; }); // 同域下的请求错误(如404)直接隐藏 if (!error.message.includes('Failed to fetch')) { iframe.style.display = 'none'; } } }); </script>
代码说明
- 跨域兼容:通过
mode: 'no-cors'避免跨域请求直接触发catch,同时添加error事件监听跨域场景下的加载失败。 - 精准错误判断:直接解析XML中的
<Code>标签内容,匹配实际返回的BlobNotFound错误标识。 - 异步逻辑优化:使用
async/await替代链式then,代码结构更清晰易读。
内容的提问来源于stack exchange,提问作者Hawkar Atta
相关产品推荐
相关产品推荐

