【问题标题】:Finding http in a href expression <a href=“javascript:;”></a> and replace it with https在 href 表达式 <a href=“javascript:;”></a> 中查找 http 并将其替换为 https
【发布时间】:2021-02-25 12:51:26
【问题描述】:

我有一些&lt;a href="javascript:; 形式的链接,我需要在其中找到http 并将其替换为https://

简单地编写一个 JS 代码来查找http 在这种情况下不起作用,我完全被卡住了。 在 &lt;a href="javascript:some very long lines;"&gt;Link&lt;/a&gt; 这样的表达式中找到链接的最佳方法是什么?

带有现实链接的图片: 非常感谢!

window.onload = function() {
    let url = document.querySelectorAll('.page-numbers');

    url.forEach((e) => {
      e.setAttribute('href', e.href.replace(/^http:\/\//i, 'https://'));
      console.log(e);

    }); 
};
<div class="pagingSection">
      <a href="javascript:WebF(new WebFform("ctl01$ctl8$g_8f9c2af0", "", false, "", "http://www.example.com/test.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=6", false, true))" class="page-numbers">Link 1</a>
      <a href="javascript:WebF(new WebFform("ctl01$ctl8$g_8f9c2af0", "", false, "", "http://www.example.com/test2.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=7", false, true))" class="page-numbers">Link 2</a>
      <a href="javascript:WebF(new WebFform("ctl01$ctl8$g_8f9c2af0", "", false, "", "http://www.example.com/test3.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=8", false, true))" class="page-numbers">Link 3</a>
    </div>

【问题讨论】:

    标签: javascript html regex replace hyperlink


    【解决方案1】:

    主要问题是您在该 HTML 中的 href 属性在您尝试放入该属性的第一个 " 时结束,因为您使用 " 来引用属性值。如果在值中使用文字 " 并且未在其中使用文字 ',请使用 ' 引用属性而不是 "。否则,您可以使用&amp;quot;,因为属性文本是 HTML 文本。

    除此之外,我会使用getAttribute 而不是href 访问器属性来获取旧值,并且您不想以^ 开始您的正则表达式,因为您想匹配其他地方比字符串的开头。这里我使用\b(字边界):

    const pageNums = document.querySelectorAll(".page-numbers");
    for (const e of pageNums) {
        e.setAttribute(
            "href",
            e.getAttribute("href").replace(/\bhttp:\/\//g, "https://")
        );
        console.log(e.href);
    }
    <div class="pagingSection">
        <a href='javascript:WebF(new WebFform("ctl01$ctl8$g_8f9c2af0", "", false, "", "http://www.example.com/test.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=6", false, true))' class="page-numbers">Link 1</a>
        <a href='javascript:WebF(new WebFform("ctl01$ctl8$g_8f9c2af0", "", false, "", "http://www.example.com/test2.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=7", false, true))' class="page-numbers">Link 2</a>
        <a href='javascript:WebF(new WebFform("ctl01$ctl8$g_8f9c2af0", "", false, "", "http://www.example.com/test3.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=8", false, true))' class="page-numbers">Link 3</a>
    </div>

    请注意,我还将该代码移出load 事件处理程序。 windowload 事件发生在页面加载过程的后期非常,等待包括图像在内的所有资源在触发前加载。不要为此使用load,如果可能,请执行以下操作之一(这是一个列表,请执行第一个适合您的目标环境/浏览器的操作):

    • type="module" 添加到script 标记,以便在HTML 完全加载并在模块范围内而不是在全局范围内运行之前它不会运行。 (所有主要的现代浏览器都支持模块。如果您需要支持 IE11,请不要这样做,但您正在使用箭头函数,所以我假设您不这样做,尽管您可能正在编译。)
    • defer 添加到script 标记,这样它在HTML 完全加载之前不会运行。连IE11都支持defer
    • script 标记放在文档末尾,就在结束&lt;/body&gt; 标记之前。
    • 将您的代码包装在 DOMContentLoaded 处理程序中,而不是 load 处理程序中。

    旁注:我建议不要首先将 JavaScript 代码放在 href 中。相反,让href 有意义,理想情况下,如果 JavaScript 被禁用,它会给您带来帮助,并使用现代事件处理(可能使用事件委托)附加您的事件处理程序,并让 JavaScript 代码阻止默认操作(按照链接)如果它运行。例如:

    const pageNums = document.querySelectorAll(".page-numbers");
    for (const e of pageNums) {
        e.setAttribute(
            "data-target",
            e.getAttribute("data-target").replace(/\bhttp:\/\//g, "https://")
        );
        console.log(e.href);
    }
    
    // The handler
    document.body.addEventListener("click", function(event) {
        const link = event.target.closest(".page-numbers");
        if (link) {
            event.preventDefault();
            const form = link.getAttribute("data-form");
            const target = link.getAttribute("data-target");
            WebF(new WebFform(form, "", false, "", target, false, true));
        }
    });
    <div class="pagingSection">
        <a href="#some-meaningful-value" data-form="ctl01$ctl8$g_8f9c2af0" data-target="http://www.example.com/test.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=6" class="page-numbers">Link 1</a>
        <a href="#some-meaningful-value" data-form="ctl01$ctl8$g_8f9c2af0" data-target="http://www.example.com/test2.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=7" class="page-numbers">Link 2</a>
        <a href="#some-meaningful-value" data-form="ctl01$ctl8$g_8f9c2af0" data-target="http://www.example.com/test3.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=8" class="page-numbers">Link 3</a>
    </div>

    现在您不必根据您是否使用"' 作为属性分隔符、您的JavaScript 代码是否在脚本文件中等来处理转义引号或选择引号。

    事实上,想想看,处理程序甚至可以为你处理http:// => https:// 的事情:

        const link = event.target.closest(".page-numbers");
        if (link) {
            event.preventDefault();
            const form = link.getAttribute("data-form");
            // (Using `^` now because it *is* at the beginning of the string)
            const target = link.getAttribute("data-target").replace(/^http:\/\//g, "https://");
            WebF(new WebFform(form, "", false, "", target, false, true));
        }
    });
    <div class="pagingSection">
        <a href="#some-meaningful-value" data-form="ctl01$ctl8$g_8f9c2af0" data-target="http://www.example.com/test.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=6" class="page-numbers">Link 1</a>
        <a href="#some-meaningful-value" data-form="ctl01$ctl8$g_8f9c2af0" data-target="http://www.example.com/test2.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=7" class="page-numbers">Link 2</a>
        <a href="#some-meaningful-value" data-form="ctl01$ctl8$g_8f9c2af0" data-target="http://www.example.com/test3.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=8" class="page-numbers">Link 3</a>
    </div>

    【讨论】:

    • @t-j-crowder 感谢您的建议!这里有人提到链接格式不正确。我编辑了我的帖子,以我看到的方式添加带有链接的图像。在这种情况下,您的解决方案仍然适用吗?如果我单击开发控制台中的链接,我会得到那些很长的行,这些行被剪掉了一点以避免显示整个信息。
    • @JustMe - 是的,仍然适用,除了您的原始问题在链接中的代码与图像中的代码不同,因此您需要为此调整上述内容。我添加到答案顺便说一句。编码愉快!
    • @RokoC.Buljan - 这是一个有序的替代品列表,最好到最少。 :-) 我已经澄清了。
    • @t-j-crowder 我尝试了您的第一个 sn-p 和 console.log 报告将 http 正确转换为 https 但我也看到一个错误:Uncaught TypeError: Cannot read property 'replace' of null at &lt;anonymous&gt;:5:31 (anonymous) @ VM10308:5 这可能是什么原因?
    • @JustMe - 听起来.page-numbers 元素之一没有href 属性。您可以添加一个守卫:const value = e.getAttribute("href"); if (value) { e.setAttribute( "href", value.replace(/\bhttp:\/\//g, "https://")); }
    【解决方案2】:
    • 使用setAttributegetAttribute 定位元素的"href" 属性。
    • String.prototype.replace$&amp; 一起使用替换模式匹配的子字符串
    • (PS:确保在 HTML 中使用正确的引号)
    • 始终使用 Element.addEventListener() 而不是 on* 处理程序(除非您从内存中创建全新的元素),以免覆盖其他分配的处理程序。

    window.addEventListener("load", () => {
      const EL_anchors = document.querySelectorAll('.page-numbers');
      EL_anchors.forEach(EL =>
        EL.setAttribute("href", EL.getAttribute("href").replace(/\bhttp(?=:\/\/)/, "$&s"))
      );
    });
    <div class="pagingSection">
      <a href='javascript:WebF(new WebFform("ctl01$ctl8$g_8f9c2af0", "", false, "", "http://www.example.com/test.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=6", false, true))' class="page-numbers">Link 1</a>
      <a href='javascript:WebF(new WebFform("ctl01$ctl8$g_8f9c2af0", "", false, "", "http://www.example.com/test2.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=7", false, true))' class="page-numbers">Link 2</a>
      <a href='javascript:WebF(new WebFform("ctl01$ctl8$g_8f9c2af0", "", false, "", "http://www.example.com/test3.aspx?cor=%20;403-7e1ee457616b%7%20;0374d4027-5a27-4421-9771-6326d4746a20%7%20ol;&areaId=%=8", false, true))' class="page-numbers">Link 3</a>
    </div>
    \b         << Word boundary
    http       << Match substring (Reused later with the .replace() `$&` pattern)
    (?=:\/\/)  << Positive lookahead: followed by "://" 
    

    .replace() 的第二个参数模式的作用:

    $&   << insert the matcher "http" substring
    s    << insert the character "s"
    

    要全局替换,您还可以使用g 标志:/\bhttp(?=:\/\/)/g

    【讨论】:

      【解决方案3】:

      您只需将匹配的字符串放入括号中:

      let string = "http://www.test.com";
      string.replace(/(http:\/\/)/, "https://");
      

      【讨论】:

      • 不,你没有。如果你想要一个捕获组,你只需要()
      猜你喜欢
      • 2011-12-06
      • 2015-10-16
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多