基本URL、JavaScript和Internet Explorer与Firefox的区别

18

问题:

IE、Firefox和Safari对于BASE HREF以及JavaScript window.location类型请求的处理似乎不同。首先,这是一个准确的问题描述吗?发生了什么?最好的跨浏览器解决方案是什么?

背景:

我有一个小型的PHP平面网站(实际上是一个可用性测试原型)。

我会在PHP中动态生成BASE标签的HREF值,即在我们公司的服务器上运行时:

$basehref = 'http://www.example.com/alpha/bravo/UsabilityTest/';

在我的本地开发机上,它是:

$basehref = 'http://ellen.local/delta/echo/foxtrot/UsabilityTest/';    

其中一项任务是,我收集了一些用户输入的数据,在Javascript中对其进行了一些转换,并使用以下代码将其发送到服务器:

function allDone() {
    // elided code for simplicity of stackoverflow question
    var URI = "ProcessUserInput.php?";
    URI = URI + "alphakeys=" + encodeURI( keys.join(",") );
    URI = URI + "&sortedvalues=" + encodeURI( values.join(",") );
    window.location = URI;
}

JavaScript文件(包含函数allDone())和处理PHP脚本(ProcessUserInput.php)都位于UsabilityTest的子目录中。换句话说,它们的实际URL是:

http://www.example.com/alpha/bravo/UsabilityTest/foxtrot/ProcessUserInput.php 也可以写成

$basehref . '/foxtrot/ProcessUserInput.php'

问题

IE的JavaScript似乎基本忽略了BASE HREF。因为JavaScript和PHP处理器位于同一个目录中,所以调用ProcessUserInput.php就能正常工作,输入被处理后一切正常。

但在Firefox上测试时,JavaScript似乎使用了BASE HREF,因为脚本输出被发送到:

$basehref . '/ProcessUserInput.php'

这段代码出现问题是因为ProcessUserInput.php在basehref的子目录下。然而,如果我将子目录名称添加到JavaScript中,它在IE中就不再起作用。

解决方案?

我可以想出几种解决方法:

  • 在JavaScript中读取BASE标签的HREF属性,并手动在JavaScript中将其前缀添加到var URI中,调用完全解析的绝对URL
  • 使用PHP处理.js文件,并将$basehref变量插入脚本中
  • 移动文件位置
  • 其他方法?

我相信还有其他解决方法。如何在JavaScript中处理BASE HREF,让IE和Firefox在JavaScript中应用它的方式不同,哪种方法最好?

6个回答

7
使用 window.location 的 assign 方法似乎是最直接的答案。
而不是使用
window.location = URI;

我正在使用这个:

window.location.assign( URI ); 

在IE和Firefox中都做正确的事情。


9
不,这并没有解决IE浏览器(至少到8版本)中的base href问题。当我看到问题可以如此简单地解决时,我脸上露出了微笑,但这只持续了一分钟。 - Halil Özgür
正如@Halil Özgür所提到的,这不应该成为被接受的答案。 - fritzmg

6
IE和Firefox/Safari在处理基础HREF和Javascript window.location类型请求时似乎有不同的方法。
是的,这是一个长期存在的差异,可以追溯到Netscape-vs-IE 的早期。
IE仅在与文档元素交互时强制执行基本href。因此,您可以使用createElement('a')创建一个相对href并单击它,但是将忽略基本href;将其appendChild到包含基本href的文档中,它将起作用。
在其他浏览器中,基本href被视为每个窗口的全局变量,并始终应用。哪个是正确的?似乎未经指定。最初的JavaScript文档仅说明location.hash(因此,location作为字符串应用):
表示完整的URL
因此,将其设置为相对URL似乎是一种未定义的操作。
(*:link.click()是IE和Opera支持的非标准方法)
读取BASE标签的HREF属性,手动添加前缀
如果您坚决要使用<base>,那么可能会这样做。

谢谢,正如建议的那样...我这样做了 window.location.href = document.getElementById("myBase").href + 'Company#!/companylist'; 它在IE和Chrome上都可以工作。 - Dipendu Paul

3

今天我也遇到了同样的问题,经过一番调查研究,我无法找到任何解决IE9兼容性问题的方法,这是我的项目所必需的,所以我采用了以下方法(基于jquery,但使用简单的javascript也可以实现)。

href = function(url){
    if ($("base").length > 0 ){
        location.href= $("base").attr("href")+url;
    }else{
        location.href = url;
    }
}

然后,更改

location.href= 'emp/start' 

to

href('emp/start');

3
我相信你想修改的是window.location.pathname,而不是window.location。window.location是一个Location对象,具有多个变量。因此,更改它的影响未被明确定义。但是,window.location.pathname被定义为相对于主机的路径,这正是你想要的。
如果您想了解有关您可以更改的许多变量的更多信息,请查看此处。根据Mozilla的文档,更改window.location中的任何变量都应该重新加载页面,并具有与这些更改相对应的新URL。

1
将字符串写入位置是没问题的,JS 1.0 已经记录过。请参阅 http://docs.sun.com/source/816-6408-10/location.htm#1193137 - "如果你将一个字符串分配给对象的位置属性,JavaScript 将创建一个位置对象并将该字符串分配给它的 href 属性。" - bobince

2

在链接前加上$('base').attr('href')即可(使用jQuery),或者

document.getElementBytagname('base').href

上面这一行应该写成:document.getElementsByTagName('base')[0].href - Mark Schneider

0

你可以随时使用原生JS :)

var href = document.getElementBytagname('base')[0].href

希望这能有所帮助。


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