使用Javascript覆盖或禁用meta refresh标签

21

我有一个网站,尝试使用Ajax在无需重新加载页面的情况下更新页面内容。然而,很可能许多用户将使用不支持Javascript的移动浏览器,因此我正在设计具有元刷新标记的页面,这些标记仅适用于没有Javascript的用户。是否有任何方法可以做到这一点?

我尝试将标记放置在noscript元素中,但我的原始手机浏览器无法识别它。我想也许可以设置一个cookie来记住用户的浏览器是否支持Javascript,或者有一个能够在没有Javascript的情况下工作的页面版本,并尝试使用Javascript将用户重定向到更高级的版本,但我想知道是否有更优雅的方式。有人有什么想法吗?


我认为从这个问题中我学到了,我试图做的事情很麻烦,可能不值得花费精力和处理所有问题。我想我可以像Hrishi建议的那样重定向,或者如果我希望Javascript和非Javascript页面使用相同的URL,我只能在用户选择启用它们时使用meta refresh标签,并使用cookie记住用户的选择。感谢你们所有人的回答。 - Elias Zamaria
8个回答

12

我发现noscript标签对此非常有效。例如,您可以在关闭head元素后立即放置它:

<noscript>
    <meta http-equiv="refresh" content="5;URL=http://www.example.com">
</noscript>

不需要删除带有脚本的meta标签,因为支持脚本的浏览器将忽略noscript元素中的所有内容。


你能提供更多关于你的使用细节吗?我已经在几个网站上成功使用过,并在许多桌面和移动浏览器上进行了测试。 - scscsc

10

你无法使用JavaScript覆盖meta refresh标签。

但是你可以这样做:

假设你的页面在->

http://example.net/mike.html,请将以下代码放置在那里->

<script type="text/javascript">
window.location = 'http://example.net/mike/for_Those_With_JavaScript_Enabled.html';
</script>

2
我的意思是,不是重定向JavaScript禁用的浏览器,而是重定向启用了JavaScript的浏览器。 - Hrishi
这非常聪明。它干净简洁,解决了问题。 - LandonSchropp
4
这会影响返回按钮的功能。启用 JavaScript 的用户点击返回按钮时,会陷入重定向循环中而无法返回。他们需要双击返回按钮才能摆脱这种情况。 - bluesmoon
使用JavaScript来更改浏览器的历史记录,以调整返回按钮。 - Jeremy
1
这个答案部分是错误的。如果你执行 window.onbeforeunload = function() { return 'test' };,你可以弹出一个窗口并点击“留在此页”来中止刷新。从用户体验的角度来看,这是一个可怕的选择,但它是一种停止刷新的技巧。 - a paid nerd

6

很遗憾,根据@bluesmoon's answer的说法,操作DOM已经不再起作用。

解决方法是检索原始标记,找到并替换meta refresh元素,然后使用替换后的标记编写新文档。

我不确定如何使用JavaScript检索原始标记,除了使用XMLHttpRequest发送附加请求。

在Opera中,这是我正在使用的:

Disable meta refresh 1.00.js

// ==UserScript==
// @name Disable meta refresh
// @version 1.00
// @description Disables meta refresh.
// @namespace https://dev59.com/T3A75IYBdhLWcg3wg5Zh#13656851
// @copyright 2012
// @author XP1
// @homepage https://github.com/XP1/
// @license Apache License, Version 2.0; http://www.apache.org/licenses/LICENSE-2.0
// @include http*://example.com/*
// @include http*://*.example.com/*
// ==/UserScript==

/*
 * Copyright 2012 XP1
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*jslint browser: true, vars: true, maxerr: 50, indent: 4 */
(function (window, XMLHttpRequest) {
    "use strict";

    if (window.self !== window.top) {
        return;
    }

    window.stop();

    var uri = window.location.href;

    var request = new XMLHttpRequest();
    request.open("GET", uri, false);
    request.send(null);

    if (!(request.readyState === 4 && request.status === 200)) {
        return;
    }

    var markup = request.responseText;
    markup = markup.replace(/<meta http-equiv="refresh".*\/?>/gi, "");

    var document = window.document;
    document.open();
    document.write(markup);
    document.close();
}(this, this.XMLHttpRequest));

Opera还具有内置功能,可以禁用meta刷新。无需JavaScript。

  • 右键单击网页 > 编辑站点首选项... > 网络 > 禁用“启用自动重定向” > 确定。

需要测试一下..谢谢! - TimoSolo

5

这对我非常有效!(在Chrome中尝试过)

window.stop();

5
标签在这种情况下并不好用。那搜索引擎怎么办呢?
你应该按照我在这里所描述的方式来做。你的链接应该指向完整的工作站点,就像是一个Web 2.0页面一样。然后通过事件处理程序(onclick),使用ajax来增强用户体验。
因此,ajax用户将不会跳转到链接,而是在点击时处理链接,并发送一个ajax请求到完全相同的url,但带有一个ajax GET参数。
现在,在服务器端,您必须能够通过某种方法生成整个站点。如果它是一个ajax请求,您将发送相关内容。如果不是ajax请求,则生成具有嵌入式相关部分的完整站点。
您的网站将是SEO友好的,可供移动用户使用,并且对于现代浏览器和平台上的人们进行了逐步改进。最后,即使是链接,也可以使用ajax生成的哈希链接。
真是太棒了。 :)

2
元标签为什么不好?我并不是想要用它们进行重定向。我只是想用它们刷新页面,作为没有JavaScript支持的用户的备选方案。我不明白这会影响搜索引擎的方式。我并不完全确定这是否是我想做的,但我仍然很好奇我该如何做到这一点。 - Elias Zamaria
你无法想出应该如何做,这对你来说不够吗? :) 你有检查过链接吗? - gblazex
1
我检查了链接。在我的服务器上对代码进行复杂处理以两种方式提供数据似乎有些棘手。如果我这样做,我将不得不处理一些怪异的问题。如果我在#符号之后放置URL的重要部分,并且某人收藏了该页面并尝试访问它,除非我有一些JS来加载内容,否则它不会像通常那样加载。如果用户点击返回按钮也是同样的情况。我不确定将我的URL设置成这种方式是否对搜索引擎有好处。他们可能会看到#并认为它只是指向同一页的不同部分的链接。我认为使用meta refresh标签可能更简单。 - Elias Zamaria
你根本没有读我的帖子:)) 链接应该指向完全有效的站点而不是哈希值。 事件处理程序附加到链接上。它们将发出Ajax请求并更改URL中的哈希值。如果您已经全文阅读,则会知道从外部访问这些ajax生成的URL是有效的。这在服务器端处理,而不是客户端。示例甚至证明了这一点。请下次仔细阅读... - gblazex

3

只需使用JavaScript删除元标记:

<meta http-equiv="refresh" content="2;http://new-url/" id="meta-refresh">

<script type="text/javascript">
var mr = document.getElementById("meta-refresh");
mr.parentNode.removeChild(mr);
</script>

我已将刷新超时设置为2秒,这只是一个示例。您也可以尝试1秒,但不要设置为0,因为在这种情况下javascript将无法执行。同时,0也会破坏后退按钮的可用性。 编辑2012-10-23:这似乎不再起作用了。节点仍将被删除,但浏览器似乎无论如何都会解析和保存所有meta标签。

这个能用吗?也许浏览器变得更加严格了,似乎不再起作用。可惜。 - TimoSolo
@Timothy 解决方法是检索原始标记,查找并替换元刷新元素,然后使用替换后的标记编写新文档。请参见我的答案:https://dev59.com/T3A75IYBdhLWcg3wg5Zh#13656851。 - XP1
我没有测试过,但从理论上讲,我认为这不可能工作。 Meta refresh使用http-equiv元标记来模拟Refresh HTTP头,因此也可以由HTTP Web服务器作为头发送。 由于js是在响应发送后才出现的,所以重定向头早已消失。 - Alin Mircea
@AlinMirceaCosma 这个问题讨论的是标记中包含的“标签”,而不是HTTP头。只要标记包含meta refresh(不作为头),如果JavaScript有时间执行,就可以删除meta refresh。 - XP1

2

我同意meta refresh不是这里前进的正确方式。除了galambalazs的链接外,还可以搜索“渐进增强”。

然而,在回答问题的精神下,您可以尝试以下方法。它未经测试,在所有浏览器中可能无法正常工作,但应该沿着正确的方向:

var i, refAttr;
var metaTags = document.getElementsByTagName('meta');
for i in metaTags {
    if( (refAttr = metaTags[i].getAttribute("http-equiv")) && (refAttr == 'refresh') ) {
        metaTags[i].parentNode.removeChild(metaTags[i]);
    }
}

目前还不清楚是否删除它会阻止浏览器及时刷新。


元标记不能被 JavaScript 覆盖。 - Hrishi
我在Firefox中尝试了这个(在metaTags中加上括号中的“i”)。我收到了一个JavaScript错误,说“metaTags [i] .getAttribute”。我想这是不可能的,至少不是那种方式。 - Elias Zamaria
1
这里不能使用for(i in ...)循环。in运算符遍历对象的键。在这种情况下,您需要使用常规数字循环:for(i=metaTags.length-1; i>=0; i--) { ... }。您需要向后迭代,因为removeChild会改变metaTags.length - bluesmoon

0

这是我使用的一个例子,它在Firefox上运行得非常完美!

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Redirecting</title>
</head>
<body onload="location.replace('http://www.live.comeseetv.com'+document.location.hash)">
<a href="http://www.live.comeseetv.com">Redirecting you to http://www.live.comeseetv.com</a>
</body></html>

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