栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Javascript:REGEX将所有相对Urls更改为Absolute

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Javascript:REGEX将所有相对Urls更改为Absolute

先进的HTML字符串替换功能

OP的注释,因为他请求了这样的功能:更改

base_url
为代理的base URL,以实现所需的结果。

下面将显示两个功能(代码中包含使用指南)。确保您不跳过此答案的任何部分以完全理解该功能的行为。

  • rel_to_abs(urL)
    -此函数返回绝对URL。当传递具有普遍信任协议的绝对URL时,它将立即返回此URL。否则,将根据
    base_url
    和函数参数生成一个绝对URL 。相对URL正确解析(
    ../
    ;
    ./
    ;
    .
    ;
    //
    )。
  • replace_all_rel_by_abs
    -此函数将解析 所有 出现的在HTML中具有重要意义的URL,例如CSS
    url()
    ,链接和外部资源。请参阅代码以获取已解析实例的完整列表。 以获取经过调整的实现,以 清理 来自外部源(嵌入到文档中)的 HTML字符串
  • 测试用例(在答案的底部):要测试该功能的有效性,只需将小书签粘贴在位置栏上。

rel_to_abs
- 解析相对网址

function rel_to_abs(url){      if(/^(https?|file|ftps?|mailto|javascript|data:image/[^;]{2,9};):/i.test(url))         return url; //Url is already absolute    var base_url = location.href.match(/^(.+)/?(?:#.+)?$/)[0]+"/";    if(url.substring(0,2) == "//")        return location.protocol + url;    else if(url.charAt(0) == "/")        return location.protocol + "//" + location.host + url;    else if(url.substring(0,2) == "./")        url = "." + url;    else if(/^s*$/.test(url))        return ""; //Empty = Return nothing    else url = "../" + url;    url = base_url + url;    var i=0    while(//..//.test(url = url.replace(/[^/]+/+..//g,"")));        url = url.replace(/.$/,"").replace(//./g,"").replace(/"/g,"%22") .replace(/'/g,"%27").replace(/</g,"%3C").replace(/>/g,"%3E");    return url;}

案例/示例:

  • http://foo.bar
    。已经是绝对URL,因此立即返回。
  • /doo
    相对于根:返回当前根+提供的相对URL。
  • ./meh
    相对于当前目录。
  • ../booh
    相对于父目录。

该函数将相对路径转换为

../
,并执行搜索和替换(
http://domain/sub/anything-but-a-slash/../me
http://domain/sub/me
)。


replace_all_rel_by_abs
- 转换
脚本实例内部的 所有相关URL URL(
<script>
,事件处理程序 不会
被替换,因为创建一个快速安全的过滤器来解析Javascript几乎是不可能的。

该脚本内部带有一些注释。动态创建正则表达式,因为单个RE的大小可以为 3000个 字符。

<meta http-equiv=refreshcontent=.. >
可以以各种方式混淆,因此RE的大小。

function replace_all_rel_by_abs(html){        var att = "[^-a-z0-9:._]";    var entityEnd = "(?:;|(?!\d))";    var ents = {" ":"(?:\s|&nbsp;?|&#0*32"+entityEnd+"|&#x0*20"+entityEnd+")",     "(":"(?:\(|&#0*40"+entityEnd+"|&#x0*28"+entityEnd+")",     ")":"(?:\)|&#0*41"+entityEnd+"|&#x0*29"+entityEnd+")",     ".":"(?:\.|&#0*46"+entityEnd+"|&#x0*2e"+entityEnd+")"};         var charMap = {};    var s = ents[" "]+"*"; //Short-hand for common use    var any = "(?:[^>"']*(?:"[^"]*"|'[^']*'))*?[^>]*";            function ae(string){        var all_chars_lowercase = string.toLowerCase();        if(ents[string]) return ents[string];        var all_chars_uppercase = string.toUpperCase();        var RE_res = "";        for(var i=0; i<string.length; i++){ var char_lowercase = all_chars_lowercase.charAt(i); if(charMap[char_lowercase]){     RE_res += charMap[char_lowercase];     continue; } var char_uppercase = all_chars_uppercase.charAt(i); var RE_sub = [char_lowercase]; RE_sub.push("&#0*" + char_lowercase.charCodeAt(0) + entityEnd); RE_sub.push("&#x0*" + char_lowercase.charCodeAt(0).toString(16) + entityEnd); if(char_lowercase != char_uppercase){          RE_sub.push("&#0*" + char_uppercase.charCodeAt(0) + entityEnd);        RE_sub.push("&#x0*" + char_uppercase.charCodeAt(0).toString(16) + entityEnd); } RE_sub = "(?:" + RE_sub.join("|") + ")"; RE_res += (charMap[char_lowercase] = RE_sub);        }        return(ents[string] = RE_res);    }        function by(match, group1, group2, group3){                return group1 + rel_to_abs(group2) + group3;    }        var slashRE = new RegExp(ae("/"), 'g');    var dotRE = new RegExp(ae("."), 'g');    function by2(match, group1, group2, group3){                group2 = group2.replace(slashRE, "/").replace(dotRE, ".");        return group1 + rel_to_abs(group2) + group3;    }        function cr(selector, attribute, marker, delimiter, end){        if(typeof selector == "string") selector = new RegExp(selector, "gi");        attribute = att + attribute;        marker = typeof marker == "string" ? marker : "\s*=\s*";        delimiter = typeof delimiter == "string" ? delimiter : "";        end = typeof end == "string" ? "?)("+end : ")(";        var re1 = new RegExp('('+attribute+marker+'")([^"'+delimiter+']+'+end+')', 'gi');        var re2 = new RegExp("("+attribute+marker+"')([^'"+delimiter+"]+"+end+")", 'gi');        var re3 = new RegExp('('+attribute+marker+')([^"'][^\s>'+delimiter+']*'+end+')', 'gi');        html = html.replace(selector, function(match){ return match.replace(re1, by).replace(re2, by).replace(re3, by);        });    }        function cri(selector, attribute, front, flags, delimiter, end){        if(typeof selector == "string") selector = new RegExp(selector, "gi");        attribute = att + attribute;        flags = typeof flags == "string" ? flags : "gi";        var re1 = new RegExp('('+attribute+'\s*=\s*")([^"]*)', 'gi');        var re2 = new RegExp("("+attribute+"\s*=\s*')([^']+)", 'gi');        var at1 = new RegExp('('+front+')([^"]+)(")', flags);        var at2 = new RegExp("("+front+")([^']+)(')", flags);        if(typeof delimiter == "string"){ end = typeof end == "string" ? end : ""; var at3 = new RegExp("("+front+")([^"'][^"+delimiter+"]*" + (end?"?)("+end+")":")()"), flags); var handleAttr = function(match, g1, g2){return g1+g2.replace(at1, by2).replace(at2, by2).replace(at3, by2)};        } else { var handleAttr = function(match, g1, g2){return g1+g2.replace(at1, by2).replace(at2, by2)};    }        html = html.replace(selector, function(match){  return match.replace(re1, handleAttr).replace(re2, handleAttr);        });    }        cri("<meta"+any+att+"http-equiv\s*=\s*(?:""+ae("refresh")+"""+any+">|'"+ae("refresh")+"'"+any+">|"+ae("refresh")+"(?:"+ae(" ")+any+">|>))", "content", ae("url")+s+ae("=")+s, "i");    cr("<"+any+att+"href\s*="+any+">", "href");     cr("<"+any+att+"src\s*="+any+">", "src");     cr("<object"+any+att+"data\s*="+any+">", "data");     cr("<applet"+any+att+"prebase\s*="+any+">", "prebase");         cr("<param"+any+att+"name\s*=\s*(?:""+ae("movie")+"""+any+">|'"+ae("movie")+"'"+any+">|"+ae("movie")+"(?:"+ae(" ")+any+">|>))", "value");    cr(/<style[^>]*>(?:[^"']*(?:"[^"]*"|'[^']*'))*?[^'"]*(?:</style|$)/gi, "url", "\s*\(\s*", "", "\s*\)");     cri("<"+any+att+"style\s*="+any+">", "style", ae("url")+s+ae("(")+s, 0, s+ae(")"), ae(")"));     return html;}

私有功能的简短摘要:

  • rel_to_abs(url)
    -将相对/未知URL转换为绝对URL
  • replace_all_rel_by_abs(html)
    -用绝对URL替换HTML字符串中所有与URL相关的出现。

    1. ae
      - 一个 纽约 è ntity -返回RE模式来处理HTML实体。
    2. by
      -替换 -此简短函数请求实际的url替换(
      rel_to_abs
      )。此功能可能称为数百次(如果不是数千次)。注意不要在此功能(自定义)中添加慢速算法。
    3. cr
      - ç reate ř E放置-创建并执行一个搜索和替换。
      示例:(
      href="..."
      在任何HTML标记内)。

    4. cri
      - ç reate ř E放置 n第-创建并执行一个搜索和替换。
      示例:
      url(..)
      style
      HTML标记内的all 属性内。

测试用例

打开任何页面,然后将以下书签粘贴到位置栏中:

javascript:void(function(){var s=document.createElement("script");s.src="http://rob.lekensteyn.nl/rel_to_abs.js";document.body.appendChild(s)})();

注入的代码包含上面定义的两个功能,以及如下所示的测试用例。 注意 :测试用例 不会
修改页面的HTML,但是会在文本区域(可选)中显示已解析的结果。

var t=(new Date).getTime();  var result = replace_all_rel_by_abs(document.documentElement.innerHTML);  if(confirm((new Date).getTime()-t+" milliseconds to executennPut results in new textarea?")){    var txt = document.createElement("textarea");    txt.style.cssText = "position:fixed;top:0;left:0;width:100%;height:99%"    txt.ondblclick = function(){this.parentNode.removeChild(this)}    txt.value = result;    document.body.appendChild(txt);}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/409747.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号