1

我在一个 Sharepoint 网站上工作。我无权访问 webparts 代码。我只能使用 JavaScript 更改母版页。

其中一个 Web 部件有错误。它改变了<img>一个不好的SRC值。

例子:

应该有

<img alt="img" src="http://www.apicture.png" style="margin:5px" /><br /><br />

但有

<img alt="img" src="<a href="http://www.apicture.png">http://www.apicture.png</a>" style="margin:5px" /><br /><br />

我试图匹配和替换,但 innerHtml 破坏了其他脚本。

如何用 JavaScript 修复我的问题?

编辑:

我有代码:

var markup = document.documentElement.innerHTML;
markup = markup.replace(/src=\".*?(http:\/\/[^\"]+)\"/g,'src=\"$1\"');
document.documentElement.innerHTML = markup;

但它打破了我的网页。

4

2 回答 2

5

由于 DOM 已经被破坏,您需要退后一步并尝试挽救 HTML。

1)找到破碎元素的父母。虽然 search&replace 内部document.body.innerHTML可能会起作用,但您不应该真正让正则表达式靠近大块 HTML。性能也是一个问题,尽管是一个较小的问题。

<img alt="img" src="<a href="http://...将被浏览器解析为带有源“ <a href=”的图像。

使用 jQuery,您可以简单地请求$('img[src="<a href"]')获取图像。除了在 IE<8 中,您可以使用querySelectorAll相同的选择器。如果你没有 jQuery,并且想支持 IE7,你需要使用getElementsByTagName手动过滤。

如果你真的很幸运,你可以通过getElementByID(或等效的 jQuery)找到父级。

这是简单的部分。


2) 您的 HTML 没有通过验证,并且浏览器已经做出了一些努力来修复它。你需要扭转这个过程。预测浏览器操作是有问题的,但让我们尝试一下。

让我们看看浏览器做了什么

<img src="<a href="http://www.test.com/img/image-20x20.png">http://www.test.com/img/image-20x20.png</a>" style="margin:5px" />​

这是 Chrome 和 Firefox 修复它的方式:

<img src="&lt;a href=" http:="" www.test.com="" img="" image-20x20.png"="">http://www.test.com/img/image-20x20.png" style="margin:5px" /&gt;

IE9 按img字母顺序对innerHTML(o_0) 中的属性进行排序,并且不会对<内部 src 进行 HTML 转义。IE7-8 还=""从属性中剥离。

图像属性将难以挽救,但文本内容完好无损。无论如何,可以看到模式:

应该保留从开始到<img结束的所有内容。src=不幸的是,在 IE 中,参数被重新排列,所以你也必须保留不正确的标签。src="..."本身必须被删除。在现代浏览器中,过去的一切都是[不正确的],但在 IE 中,正确的属性可能已经悄悄出现(反之亦然)。然后图像标签结束。

后面的所有内容都是真实的 URL,直到双引号。从双引号直到 HTML 转义/>是属于图像标签的属性。让我们希望它们不包含 HTML。CSS 很好(出于我们的目的)。


3) 让我们构建正则表达式:一个打开的 IMG 标记,任何属性(希望它们不包含 HTML)(捕获),src属性及其特定值(转义或未转义),任何其他属性(捕获),结束标记、URL(捕获)、更多属性(捕获)和 HTML 转义结束标记。

/<img([^>]*?)src="(?:<|\&lt\;)a href="([^>]*?)>([^"]+?)"(.*?)\/&gt;/gi

您可能对RegexPal.com 如何看待它感兴趣


它应该被替换为:具有适当属性的图像连接,并与src打捞。过滤属性可能是值得的,所以让我们选择回调替换。普通属性的键中只包含单词字符。更重要的是,普通属性通常是非空字符串(IMG 标签没有布尔属性,除非您使用服务器端地图)。这将匹配所有空属性但不匹配有效的属性键:/\S+(?:="")?(?!=)/


这是代码:

//forEach, indexOf, map need shimming in IE<9
//querySelectorAll cannot be reliably shimmed, so I'm not using that.

//author: Jan Dvorak
// https://stackoverflow.com/a/14157761/499214

var images = document.getElementsByTagName("img");
var parents = [];
[].forEach.call(images, function(i){
  if(
    /(?:<|\&lt\;)a href=/.test(i.getAttribute("src"))
    && !~parents.indexOf(i.parentNode)
  ){ 
    parents.push(i.parentNode)
  }
})

var re = /<img([^>]*?)src="(?:<|\&lt\;)a href="([^>]*?)>([^"]+?)"(.*?)\/&gt;/gi;
parents.forEach(function(p){
  p.innerHTML = p.innerHTML.replace(
    re, 
    function(match, attr1, attr2, url, attr3){
      var attrs = [attr1, attr2, attr3].map(function(a){
        return a.replace(/\S+(?:="")?(?!=)/g,"");
      }).join(" ");
      return '<img '+attrs+' src="'+url+'" />';
    }
  );
});

小提琴:http: //jsfiddle.net/G2yj3/1/

于 2013-01-04T13:06:03.157 回答
1

您可以src使用正则表达式修复属性,但它不会修复整个页面。原因是 Web 浏览器试图解析这种糟糕的 HTML 并在 JS 执行之前产生奇怪的输出(额外的元素等)。由于您不能干扰 HTML 解析/渲染引擎,因此除了更改原始内容来解决此问题外,没有其他合理的方法。

于 2013-01-04T11:11:33.293 回答