gpt4 book ai didi

javascript - 我可以在 iframe 中使用 window.location.replace 吗?

转载 作者:行者123 更新时间:2023-12-02 23:45:09 26 4
gpt4 key购买 nike

我们可以使用 window.location.replace避免历史记录,并在没有页面重新加载的情况下定位页面 anchor ,但*不在 iframe 中?
问题是违反 CSP(内容安全策略),说明 script-src 'unsafe-inline'必须启用。除非我没有定义 CSP,即使我定义了一个并允许 script-src 'unsafe-inline'它仍然给出相同的违规错误。 ie11/chrome/ff 中的结果相同。
iframe 位于同一域(在同一目录中)。

  • 在控制台中定位 iframe 并使用 window.location.replace('/samepage.html#onpage_anchor')在控制台中。
  • 有用。它以页面 anchor 为目标,无需重新加载页面,也没有历史记录。
  • 将相同的代码内嵌在 anchor 链接上,它就可以工作了。
  • 在外部脚本中使用相同的代码,得到 csp 违规错误。如果不在 iframe 中,这可以正常工作。

  • 我尝试创建一个 CSP 来允许该操作,但即使是最宽松的内容安全策略也不允许这样做。
    因此,我在允许多个文件的 plunker 上汇总了示例,以便我可以使用引用父/子页面的正确 href。
    关于 plunker 示例的说明:
  • 在这些示例中没有重现该问题。即使在 iframe 中,脚本也能完美运行。但是,相同的代码在我的本地服务器上不起作用,或者当我在 VPS 上运行它时。
  • 我怀疑 plunker 不会触发 CSP 违规,因为 plunker 通过某种抽象层向浏览器呈现内容。
  • 第一次单击父级中的 Accordion 链接时,它会导致刷新。这是因为页面最初加载它的方式没有引用 index.html。后续点击按预期工作,无需重新加载页面。在 iframe 中不是问题,因为它最初确实引用了 child.html
  • 这些是展示代码的好示例,无需更改即可使其工作(例如需要更改 href 以使其在 stackoverflow 片段中工作,如下所述)。它也很好,因为它显示了 javascript 正常工作。但它并没有显示实际问题。您仍然需要在编辑器中加载它并在本地服务器或实时托管环境上运行它以查看真正的问题。

  • Plunker 示例: With script/without history . Without script/with history

    一个条目的简单 Accordion 。足以重现问题。
    单击打开/关闭将展开/折叠 Accordion ,不需要 JS。 JS 应该做完全相同的事情,但没有历史记录。工作正常,但不在 iframe 中。
    代码片段注释:
  • 您可以运行该代码段以了解我所描述的内容,但它实际上并未演示该问题。
  • 该代码段的行为与在真实浏览器中的行为不同,javascript 不起作用。
  • 该代码段显示了代码,但应在 iframe 中运行以查看问题。在 iframe 之外运行它以查看差异以及它应该如何工作。
  • 由于链接如何与 JS(替换整个 url)一起工作,它们实际上是 必须像这样href="/thispage.html#ac1"而不仅仅是 href="#ac1"因为它们出现在代码段中(无法定位代码段中的实际 html 页面)。所以如果你 在你的编辑器中试试这个 (请做),然后记得把链接改成这种格式this_document.html#anchor所以他们仍然是 同页 anchor ,但 page.html 包含在链接中。

  • $(document).ready(function() {

    // anchor links without history
    $.acAnch = function(event) {
    event.preventDefault();
    var anchLnk = $(event.target);
    var anchTrgt = anchLnk.attr('href');
    window.location.replace(anchTrgt);
    }
    // listen for anchor clicks
    $('.accordion').on('click', 'a', $.acAnch);

    });
    div#sample.example .accordion {
    margin-left: 50px;
    margin-top: 50px;
    }

    div#sample.example section {
    box-sizing: border-box;
    clear: both;
    position: relative;
    display: block;
    width: 300px;
    height: 32px;
    padding: 0;
    background-color: #fff;
    box-shadow: inset 0 0 1px 1px #000;
    overflow: hidden;
    }

    div#sample.example section:target {
    height: auto;
    }

    div#sample.example a {
    box-sizing: border-box;
    display: block;
    float: right;
    width: 50%;
    height: 32px;
    margin: 0;
    padding: 4px;
    text-align: center;
    font-size: 16px;
    color: #000;
    background-color: #fff;
    box-shadow: inset 0 0 1px 1px #000;
    }

    div#sample.example p {
    box-sizing: border-box;
    clear: both;
    display: block;
    width: 100%;
    padding: 16px;
    margin: 16px 0 0;
    text-align: center;
    color: #000;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="sample" class="example">
    <article class="accordion">
    <section id="ac1">
    <a href="#ac0" class="ac-close">Close</a>
    <a href="#ac1" class="ac-open">Open</a>
    <div class="ac-content">
    <p>The elephants talking in their sleep kept me up so late.</p>
    </div>
    </section>
    </article>
    </div>

    $(document).ready(function() {

    // anchor links without history
    $.acAnch = function(event) {
    event.preventDefault();
    var anchLnk = $(event.target);
    var anchTrgt = anchLnk.attr('href');
    window.location.replace(anchTrgt);
    }
    // listen for anchor clicks
    $('.accordion').on('click', 'a', $.acAnch);

    });
    这很简单:
  • acAnch 函数采用 href属性并将其放入 window.location.replace() .
  • 监听 Accordion 内 anchor 的点击以运行 acAnch 函数。

  • 所以脚本所做的就是运行 window.location.replace('/this_same_page.html#on_page_anchor')如果你把它放在控制台中,它就可以工作,不会违反 CSP。但是从外部脚本运行它不起作用。
    链接上的内联工作正常:
    onclick="event.preventDefault();window.location.replace('/thispage.html#acc0');"
    onclick="event.preventDefault();window.location.replace('/thispage.html#acc1');"
    把它放在各自的链接上效果很好,但我真的不想使用这样的内联脚本。必须有一种方法可以使用外部脚本执行此操作。
    我尝试在父级而不是 iframe 中运行 javascript(当然,修改以选择子级中的链接)。相同的 CSP 错误结果。
    我为什么要这样做?那么该站点比示例复杂得多。 iframe 中的 anchor 工作正常,但它们添加了历史记录。如果你在没有 javascript 的情况下运行上面的代码,(或者只是运行代码段),打开和关闭 Accordion 几次,然后使用后退按钮,它将通过打开关闭状态返回。
    我不介意历史记录,但如果它在 iframe 中,当您离开父页面然后返回它时,iframe 中的历史记录被破坏。返回不再返回 Accordion 状态,而是继续重新加载 iframe。最初, anchor 不会导致 iframe 重新加载,而只是逐步执行 Accordion 状态历史记录,这工作正常,直到您离开页面并返回。然后返回不再经历 Accordion 状态,而只是经历一堆相同的 iframe 重新加载。这是对用户非常不友好的行为。
    如果有另一种可行的方法,我不需要使用 location.replace。不过,我尝试了许多其他方法,我发现可以实现相同结果的方法通常会导致相同的错误。
    目标只是在 iframe 内激活页面上的 anchor 链接,无需重新加载,也无需历史记录。
    内联脚本有效。我们可以让它在外部 .js 文件中工作吗?

    最佳答案

    这可能不是问题,但您提到这是您本地服务器上的问题,我注意到您的代码依赖于相对链接。
    如果您没有正确设置,您可能通过 file://协议(protocol)或以某种方式使用本地主机提供资源,不被识别为有效的 TLD,这将导致 file://协议(protocol)为默认值,或使 CSP 无效
    无论如何,请尝试使用绝对 URL,看看是否能解决问题

    关于javascript - 我可以在 iframe 中使用 window.location.replace 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58849390/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com