在 Meta 刷新之前运行 JavaScript 代码是否可行?

4

在此期间,我们一直在使用这个可靠的网站重定向HTML/JavaScript代码。

<!DOCTYPE HTML>
<html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="refresh" content="1;url=https://www.nosuchwebsite.com">
        <script type="text/javascript">
            window.location.href = "https://www.nosuchwebsite.com"
        </script>
        <title>Page Redirection</title>
    </head>
    <body>
        <!-- Note: don't tell people to `click` the link, just tell them that it is a link. -->
        If you are not redirected automatically, follow the <a href='https://www.nosuchwebsite.com'>nosuchwebsite</a>
    </body>
</html>

现在,我们希望在重定向之前执行Google Analytics跟踪代码。
<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-xxxxxxxx-x']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>

我意识到,meta "refresh" 可能会比 JavaScript 跟踪代码先执行。 我想知道,是否有任何方法使 Google Analytics 跟踪代码在 meta "refresh" 之前运行

5个回答

2

长脚本的解决方案

如果脚本需要运行很长时间,而我们不确定具体需要多少秒钟,就不想指定时间。

因此,我们的想法是从 meta 标签中获取重定向 URL 并进行重定向。

  1. 停止刷新,
window.stop();
  1. 你会编写脚本吗?

  2. 最后从meta中获取URL并重定向到它。

window.location = document.querySelector( '[http-equiv="refresh"]' ).content.split( 'url=' )[1];

这里有一个例子

// STEP 1: Stop currect redirection
window.stop();

// STEP 2: Do your script stuff
// promise? async/await? Do wtf you want.
const msgEl = document.getElementById( 'messages' );
const addMsg = msg => msgEl.innerHTML += msg + '<br>';
setTimeout( () => addMsg( 'Let me at least do my nails.' ), 1000 );
setTimeout( () => addMsg( 'Aah, I\'m having a bad hair day :(' ), 2000 );
setTimeout( () => addMsg( 'Almost done...' ), 3000 );
setTimeout( () => addMsg( 'Ok, just a (three) second(s)...' ), 4000 );
setTimeout( () => {
  addMsg( 'Redirecting...' );
  // STEP 3: Redirect, Finally done with every we wanted to do.
  window.location = document.querySelector( '[http-equiv="refresh"]' ).content.split( 'url=' )[1];
}, 7000 );
/* Arbitrary CSS for presentation purposes only */

p, h3, small {
  font-family: sans-serif;
  font-weight: 300;
  line-height: 2
}

p {
  font-size: 14px;
}

code {
  font-family: monospace;
}
<!-- Resides somewhere inside <head> tag. -->
<meta http-equiv="refresh" content="0;url=https:///google.com/">

<!-- Arbitrary html for illustration -->
<h3>
Please wait while you are redirected with the mighty <code>meta refresh</code>.
</h3>

<p id='messages'></p>

<small><b>Spoiler:</b> Redirection will be stopped even though <code>meta[http-equiv="refresh"]</code> refreshes in 0 seconds.</small>


这在HTML文件中是如何实现的?我不明白所提议的HTML如何触发JS代码。JS代码位于哪里?为什么需要CSS? - Suraj
JS代码可以在HTML中的<script>标签内或单独的JS文件中出现。关键部分是使用window.stop()停止刷新,然后根据需要执行脚本操作。最后重定向到meta标签中的URL。 - shramee
CSS和HTML只是用于展示的。关键部分是__停止刷新__,然后在完成所有操作后重定向自己 - shramee
什么保证JavaScript代码在刷新之前运行以停止重定向?只是因为http-equiv有1秒的等待吗?如果将其设置为0,它是否有效?如果不是,那么我认为这与其他发布的解决方案实际上是等效的,只是更可靠,因为您正在停止重定向,但仍需要在<head>中执行http-equiv之前到达那里。 - Suraj
它确实会 :) 即使是0 ;) - shramee
显示剩余2条评论

1
如果您将重定向添加到Google Analytics脚本中,就像下面的HTML JavaScript DOM一样,会怎么样呢?

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxxx-x']);
_gaq.push(['_trackPageview']);

(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);

document.getElementById("metaTag").innerHTML='<meta http-equiv="refresh" content="1;url=https://www.nosuchwebsite.com">'
})();
<!DOCTYPE HTML>
<html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <meta id="metaTag">
        <title>Page Redirection</title>
    </head>
    <body>
        <!-- Note: don't tell people to `click` the link, just tell them that it is a link. -->
        If you are not redirected automatically, follow the <a href='https://www.nosuchwebsite.com'>nosuchwebsite</a>
    </body>
</html>

感谢并致以最好的问候!

根据悬赏评论(并符合提问者的要求),解决方案应使用 http-equiv="refresh" - Suraj
@Suraj 哦,对不起。我忘记了那个元部分。我刚刚编辑了我的答案。现在可以使用吗? - Vishal Kalansooriya
那么在这种方法中,http-equiv是动态插入的吗?如果是,聪明!我认为这可能会干扰Google和其他搜索引擎确定页面已移动的能力? - Suraj
@Suraj https://developers.google.com/search/docs/advanced/javascript/javascript-seo-basics#:~:text=Googlebot%20supports%20web%20components,at%20the%20rendered%20HTML. 我认为这里有你问题的答案。我猜测,这不会影响SEO,因为Googlebot和其他搜索引擎可以使用渲染后的HTML内容 :) - Vishal Kalansooriya
谢谢!我会测试并查看它是否有效。实际上,我正在使用Plausible Analytics而不是Google,但解决方案应该是相同的。我会在一两天内回报。 - Suraj
@Suraj 我希望在这种情况下是这样的 :) - Vishal Kalansooriya

0
这是一个与Plausible兼容的解决方案(在重定向之前向Plausible发送事件)。

index.html

<!DOCTYPE HTML>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="refresh" content="5;url="[TARGET_URL_HERE]">
        <link rel="canonical" href="[TARGET_URL_HERE]" />
        <script data-domain="[SOURCE_DOMAIN_HERE]" src="https://plausible.io/js/script.manual.js"></script>
        <script src="plausible-redirect.js"></script>
    </head>
    <body>
        <h1>
            The page been moved to <a href=[TARGET_URL_HERE]</a>
        </h1>
    </body>
</html>

plausible-redirect.js

// We would like to record a pageview with Plausible before redirecting so that we can capture data such as the referrer, search terms, etc.
// After the redirect, Plausible records the pageview for the target domain with the old domain
// as the referrer - it's all lumped together without any visibility into the true referral data.
// This is the best approach we could come up with in collaboration with Plausible support and a bounty
// that was added to this StackOverflow question:
// https://dev59.com/pnPYa4cB1Zd3GeqPj4Zk
// The page initiating the redirect should include a meta http-equiv="refresh" tag, but set a high timeout.  
// This enables search engines to know, when parsing, that the page is redirected (in case it matters for SEO).
// That page should also include the manual version of Plausible's JS and finally include this file.
// This code calls Plausible to record the pageview, and registers a callback and performs the redirect.
// This ensures that the pageview is fully recorded before the refresh occurs.  If the refresh is simply inlined
// then, in FireFox, we've found that the pageview is not recorded.  We also add a 50 ms delay so that the browser
// can record a 202 for the POST (doesn't seem to be strictly required - we see the event is send to Plausible and,
// sometimes we get the 202 and other times we don't - likely just a timing issue).
window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) };
redirect = async () => { 
    await new Promise(r => setTimeout(r, 50));
    window.location = document.querySelector( '[http-equiv="refresh"]' ).content.split( 'url=' )[1]; 
}
plausible("pageview", {callback: redirect})

0

只需增加 meta refresh 命令的秒数,它将在重定向到新页面之前等待那么长时间。这将允许您的 JavaScript 同时执行。

<meta http-equiv="refresh" content="1;url=https://www.nosuchwebsite.com">
                                    ^

可以

<meta http-equiv="refresh" content="3;url=https://www.nosuchwebsite.com">

但是,它足够安全可靠吗?我们只是假设在3秒后JavaScript执行完成了? - Cheok Yan Cheng
3秒钟对于Google脚本来说太长了,远远超过了所需时间。但是如果你发现这不够用,当然可以增加持续时间。 - Hanky Panky

0
或者不要使用meta refresh,改用Javascript刷新,并在<noscript>块中添加meta refresh以确保即使禁用了Javascript,分析仍能正常工作。

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