jQuery解析HTML而不加载图片

18
我从其他页面加载HTML以提取和显示该页面的数据:
$.get('http://example.org/205.html', function (html) {
    console.log( $(html).find('#c1034') );
});

这确实可以工作,但由于 $(html) ,我的浏览器试图加载在 205.html 中链接的图片。这些图片不存在于我的域名上,因此我会得到很多 404 错误。

有没有一种方法可以像 $(html) 一样解析页面,但不需要将整个页面加载到我的浏览器中?

7个回答

17

实际上,如果您查看jQuery文档,它说您可以将“owner document”作为第二个参数传递给$

因此,我们可以创建虚拟文档,这样浏览器就不会自动加载提供的HTML中存在的图像:

var ownerDocument = document.implementation.createHTMLDocument('virtual');
$(html, ownerDocument).find('.some-selector');

我没有测试过这个,但是在我看来,这似乎是解决这个问题的最佳方案。如果它不起作用,请告诉我。你仍然可以使用下面的字符串替换,但我一直认为这是一个糟糕的解决方案 - PiTheNumber
谢谢,这正是我需要的。 - Wim Pruiksma

17
使用正则表达式并删除所有的标签。
 html = html.replace(/<img[^>]*>/g,"");

那对我有用。注意,这不适用于背景图片样式。因此,我猜你需要一个XML解析器。谢谢! - PiTheNumber
@PiTheNumber和Bhuvan:顺便说一下,那个正则表达式很容易被绕过:http://jsbin.com/wejosoku/1。我认为它可以通过重复应用来解决,但我不想把我的网站赌在没有人能够找到绕过它的方法上。正则表达式基本上不适合进行重要的HTML解析。 - T.J. Crowder
@T.J.Crowder 我知道这不安全,但在我的情况下,我可以信任其他域的HTML代码。正则表达式对大多数事情都很糟糕,我强烈建议尽可能避免使用它。我很乐意看到另一个解决方案,但完整的HTML解析器对于这个问题来说太大了。 - PiTheNumber

4

非常抱歉重新提出一个旧问题,但这是在搜索如何尝试停止解析html从加载外部资源时的第一个结果。

我采取了Nik Ahmad Zainalddin的答案,但其中存在一个弱点,就是在<script>标签之间的任何元素都将被清除。

<script>
</script>
Inert text
<script>
</script>

在上面的例子中,Inert text和脚本标签一起被删除了。我最后做的是:
html = html.replace(/<\s*(script|iframe)[^>]*>(?:[^<]*<)*?\/\1>/g, "").replace(/(<(\b(img|style|head|link)\b)(([^>]*\/>)|([^\7]*(<\/\2[^>]*>)))|(<\bimg\b)[^>]*>|(\b(background|style)\b=\s*"[^"]*"))/g, "");

此外,我增加了删除iframe的功能。希望这能帮助到某些人。

3

1
也许我错过了什么 - 但是这个例子会导致图像重新加载。请参见https://jsfiddle.net/Abeeee/deg3846s/4/的示例 - 如果您显示网络跟踪的Devtools,则会看到“richard”被加载两次。 https://dev59.com/BGUp5IYBdhLWcg3wtZE0#50194774似乎有可行的解决方案。 - user1432181

1
以下正则表达式可以替换ajax加载返回的数据字符串中的所有出现的 <head>, <link>, <script>, <style>,包括backgroundstyle属性。
html = html.replace(/(<(\b(img|style|script|head|link)\b)(([^>]*\/>)|([^\7]*(<\/\2[^>]*>)))|(<\bimg\b)[^>]*>|(\b(background|style)\b=\s*"[^"]*"))/g,"");

测试正则表达式: https://regex101.com/r/nB1oP5/1

我希望有一种更好的方法来解决这个问题(而不是使用正则表达式替换)。


1
你可以使用jQuery的remove()方法来选择图像元素。
console.log( $(html).find('img').remove().end().find('#c1034') );

或者从HTML字符串中删除它们。类似于


console.log( $(html.replace(/<img[^>]*>/g,"")) );

关于背景图片,你可以这样做:
$(html).filter(function() {
    return $(this).css('background-image') !== ''; 
}).remove();

第一个没有起作用。$(html)已经加载了页面。第二个起作用了。谢谢! - PiTheNumber

0

不必完全删除所有img元素,您可以使用以下正则表达式来删除所有src属性:

html = html.replace(/src="[^"]*"/ig, "");

这会破坏HTML,因为<img>元素的src属性是必需的。请参阅https://developer.mozilla.org/de/docs/Web/HTML/Element/img。 - PiTheNumber
这可能是真的,但对于那些在CSS选择器中使用img标签或需要从图像属性之一获取数据的人来说,这是一个很好的替代解决方案。 - Revadike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接