考虑以下情况。用户提交包含文件输入字段的表单。然后,在处理完上传后,服务器会将浏览器重定向到包含#hash-part
的地址。如果浏览器是IE7 / 8,它将在哈希标记后丢弃该部分(包括#
本身)。此外,它将执行此操作,无论是否发生实际文件上载或用户只是将文件字段留空。以下代码说明了它。
<? if (isset($_POST['sent'])) {
header("Location: " . basename($_SERVER['PHP_SELF']) . "#test");
die();
}
?><!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
<input type="hidden" name="sent" value="1" />
<input type="file" name="test" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
提交表单后,IE 7/8在地址栏中显示与以前相同的地址,而其他浏览器(和IE 9/10)被正确地重定向到index.php #test。当用文本输入替换文件输入时,问题就消失了。
这是一个错误还是某种安全措施?有解决方法吗?
答案 0 :(得分:1)
我最终在IE 7/8上使用双重定向。我换了
header("Location: " . basename($_SERVER['PHP_SELF']) . "#test");
与
if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(^|[^a-zA-Z])(MSIE|msie) [678]($|[^\d])/', $_SERVER['HTTP_USER_AGENT'])) // If IE 6, 7 or 8
header("Location: redirect.php?to=" . urlencode(basename($_SERVER['PHP_SELF']) . "#test"));
else // For sane browsers
header("Location: " . basename($_SERVER['PHP_SELF']) . "#test");
并创建了一个简单的重定向脚本redirect.php
:
<? if (isset($_GET['to']))
header('Location: ' . $_GET['to']);
答案 1 :(得分:0)
在使用javascript实现oauth流程时,我不得不处理一个奇怪的互联网探测器。
似乎可以通过在主题标签前面直接放置一个斜杠来解决问题。所以而不是file.php#werewwer
make file.php/#werwer
但我不知道为什么......我认为这是一个错误。
主题标签永远不会被传送到服务器。它只是客户端。我认为IE只是提前删除它......
另一种可能性是使用元重定向而不是标头重定向。这似乎有效。你也可以使用javascript附加到网址...不知道这是否适合你的用例。