【发布时间】:2014-04-24 01:54:17
【问题描述】:
我面临一个我确信很常见的问题。我找到了很多解决这个问题的方法,它们各有优缺点。我将在这里发布我发现的内容(我相信这对其他人有用),我希望你能指出我正确的方向。
基本上,这是我的场景:
- 我有一个 PHP 网页:
http://example.com/page_with_content_a_or_b.php。 - 当没有指定 POST 参数时,该页面返回
Content A,如果有,则返回Content B。 - 假设用户在浏览器中输入上一个 URL(GET 请求)连接到我的页面。
- 我的服务器返回带有
Content A的页面。 - 用户的网络浏览器通过 JavaScript 决定将
Content A替换为Content B。
问题:JavaScript 如何替换内容?
嗯,正如我所说,我一直在寻找不同的解决方案,但似乎没有一个是完美的。
为了讨论每个可能的解决方案,让我向您介绍每个版本的 HTML 代码:
内容 A 的 HTML
<html>
<head>
<link rel="stylesheet" type="text/css" href="style_A.css">
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="gallery-animator.js"></script>
</head>
<body>
<div class="gallery"><!-- images here --></div>
<p>Content A</p>
<script type="text/javascript" src="content-b-loader.js"></script>
</body>
</html>
内容 B 的 HTML
<html>
<head>
<link rel="stylesheet" type="text/css" href="style_B.css">
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="gallery-animator.js"></script>
</head>
<body>
<div class="gallery"><!-- images here --></div>
<p>Content B</p>
</body>
</html>
两个版本之间的差异
如您所见,在示例中,两个版本非常相似,但并不完全相同。总的来说,这些是我可能会遇到的差异:
- 所有或部分或没有导入的样式表可能不同。
- 所有或部分或没有导入的 javascript 可能不同。
- 内联样式表和/或 javascript 可能存在差异。
- 内容不同,但可能只有一点点不同,也可能完全不同。
-
Content B不包含加载自身的脚本(Content A中的最后一个脚本)。
可能的解决方案
用 document.open()、document.write() 和 document.close() 替换内容
我实现的第一个解决方案如下:
content-b-loader.js(选项 1)
$(document).ready(function() {
$.ajax({
type: 'POST',
url: window.location.href,
data: { load_content_b: 'true' },
success: function( html ) {
document.open();
document.write(html);
document.close();
}
});
});
显然,该解决方案可以正常工作。但是,在某些情况下我会遇到问题。例如,在我的示例中,两个内容都加载了一个名为 gallery-animator.js 的脚本。假设这个脚本如下:
gallery-animator.js
var galleryInterval = setInterval(function() {
// Fade out current image and fade in the next one
$("body > div.gallery > img")...
}, 5000);
在content-b-loader.js 中执行脚本后,画廊动画会出现两次超时。结果,动画看起来很乱(两个图像同时移动,或者根本不工作)。
看起来序列document.open()、document.write(html)和document.close()不会停止并替换原始脚本。
使用 POST 数据重定向(使用表单)
另一种解决方案是进行in this previous question 中描述的重定向。该解决方案的作用就像一个魅力:一方面,我加载了我需要加载所需的 POST 数据的 URL,这意味着我将获得 Content B,另一方面,Content B 加载在一个“新页面”,这意味着Content A加载的脚本不再存在。
这里的问题?如果我使用Content B 刷新页面,我会收到一条警告,指出“即将重新提交 POST 数据”。这是不可取的,因为它看起来让用户感到困惑(我不希望她知道她已被重定向到新页面)。
我知道有一个名为PRG (Post-Redirect-Get) 的解决方案可以避免这个特定问题。但是,它需要 Content B 可以使用 GET 请求访问(使用 GET 参数或 COOKIES,我都不能使用)。
使用 iframe
我发现的最后一个解决方案也很有趣。基本上,它隐藏(或清空)Content A 的正文,在页面中添加一个 iframe,并在其中加载 Content B:
content-b-loader.js(选项 3)
$(document).ready(function() {
$.ajax({
type: 'POST',
url: window.location.href,
data: { load_content_b: 'true' },
success: function( html ) {
$("body").css('', ''); // Remove all paddings and margins
$("body").empty();
$("body")append('<iframe id="content" seamless="seamless"' +
'src="anchor.html"></iframe>');
// Initialize vars in anchor.html and call the redirect functions
document.getElementById('content').contentWindow.url = window.location.href;
document.getElementById('content').contentWindow.options = {
load_content_b: 'true'
};
document.getElementById('content').contentWindow.redirect();
}
});
});
anchor.html
此页面实现了第二种解决方案(它使用 POST 重定向)。
<html>
<head>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.redirect.min.js"></script>
<script type="text/javascript">
var url;
var options;
function redirect(){
$().redirect(url, options, 'POST');
}
</script>
</head>
<body></body>
</html>
通过使 iframe 与窗口视图一样大,我可以显示替代内容。如果用户刷新网页,刷新的页面就是“容器”页面(原来有Content A的那个),所以根本不会出现警告。
但是,我在使用此解决方案时面临的问题是:
- 用户可以禁用 iframe。如何检测 iframe 是启用还是禁用?
- 当用户单击框架中的链接(或提交表单)时,会在 iframe 中打开“新页面”。这不是我想要的:我希望它在主窗口中打开。我该怎么做呢?我知道有
basedirective 链接...但是表单呢?以及执行重定向的 JavaScript 代码? - iframe 中的所有内容都可以正常工作吗?响应式主题、javascript……据我所知,它们可以,但我忽略了用户是否可以限制 iframe 的功能。
TL;DR - 结论
我有一个页面http://example.com/page_with_content_a_or_b.php。该页面使用 GET 请求访问时返回 Content A,使用 POST 访问时返回 Content B。当用户键入 URL 时,她会得到 Content A,而 Content B 是使用 JavaScript 加载的。
所有解决方案都会带来问题:
- 使用 document.open()、document.write()、document.close(),脚本会变得混乱。
- 使用 POST 重定向,刷新页面会弹出警告
- 对于 iframe,它们并不总是可用,而且我不知何故被“困”在其中。
有什么想法吗?我错过了什么吗?有没有首选的方法来做我想做的事情?
非常感谢!
【问题讨论】:
-
虽然我很感激在这篇文章上付出的努力,但我觉得我并不完全理解这篇文章试图解决的问题。您在问题的开头列出了 5 个步骤,但您能否返回并编辑这些步骤以显示其中是否有任何您必须遵守的要求?我想跳到第二部分(备用 css 样式表),然后是第三部分(ajax 请求)和第四部分(哇,iframe!?)没有解决真正的问题,但我不确定我知道问题是什么.你能用“遗留代码要求”或“我希望它这样做”和“愿望清单”等标记数字 1-5 吗?
-
jsfiddle 会非常有帮助,即使它是问题的精简版。
标签: javascript html redirect post replace