在子iframe中使用window.location的相对url

时间:2010-02-17 12:45:00

标签: javascript iframe path location

我遇到与iframe相关的问题。

我有一个iframe(child)的文档(父级)。如果父文档调用子项中的一个函数,该函数使用window.location将子URL更改为相对URL,则该url将变为相对于父文档。让我来说明一下。

  

父文件:/test/parent.html

     

子文档:/projects/child.html

子代码:

function moveOn(){
    window.location.href = "newPage.html";
}

家长代码:

childDocument.contentWindow.moveOn();

结果: 子文档尝试访问 /test/newPage.html 而不是 /projects/newPage.html

有没有办法解决这个问题?我处于这样一种情况:我无法在子文档代码中进行更改,只能在父文档中进行更改。

谢谢, NIK

编辑:

这是实际代码

在父级(/testr/testr.html)中:

testr.appHolder = $("childIframe"); 
testr.appHolder.src = "../projects/test.html"; 
testr.functionName = "moveOn"; 
testr.appHolder.contentWindow[testr.functionName]();

在孩子(/projects/test.html)中:

function moveOn(){ 
  window.location.href = "newPage.html"; 
}

这是实际代码

在父级(/testr/testr.html)中:

testr.appHolder = $("childIframe"); 
testr.appHolder.src = "../projects/test.html"; 
testr.functionName = "moveOn"; 
testr.appHolder.contentWindow[testr.functionName]();

在孩子(/projects/test.html)中:

function moveOn(){ 
  window.location.href = "newPage.html"; 
}

3 个答案:

答案 0 :(得分:4)

最后,一个完整的解决方案!

childDocument.contentWindow.setTimeout( childDocument.contentWindow.moveOn, 0 );

这要求子文档在零毫秒内执行给定的函数(moveOn),并且它在子上下文中执行,即使在Internet Exploder中也是如此。

Booyah。

答案 1 :(得分:-1)

HTML规范说:

  

当设置[location属性]时,[browser]必须相对于条目脚本的基本URL解析参数,如果成功,则必须将浏览上下文导航到指定的URL。

获得您所追求的行为的一种(hacky)方式是直接编辑pathname的{​​{1}}属性:自己有效地实现相对网址的解析。

在您的情况下,您可以使用您孩子的现有网址“手动”编辑网址。

Dotdot解决方案

一种“聪明”的方法是通过附加一个斜杠将文件名转换为“目录”,然后用“dotdot”删除它,然后是你想要的相对网址。

location

(此代码也适用于孩子,但你提到你无法更改子代码。)

了解其工作原理。

路径以<childDocument.contentWindow.location.pathname += "/../newPage.html";

开头

然后你附加它,得到
/projects/child.html

浏览器将此解析为
/projects/child.html/../newPage.html

不幸的是,我想这对你来说不是一个完美的解决方案。听起来每个“子”页面都包含指向链中下一页的硬编码链接,可以是任何页面。获取任何给定子页面的“下一个”相对URL将需要孩子的合作。

如果子页面以可预测的方式命名,并且您知道页面总数,并且您知道子目录的基本URL,则可以让父控件正确控制子项。那是很多ifs。

旁注:我正在研究一种更优雅,更强大的解决方案。手指交叉。

答案 2 :(得分:-1)

啊哈。我找到了baseURI属性。现在我们正在谈论。

基本问题是执行代码(父代)的文档的baseURI被设置为父代的位置。您希望在更改页面的位置之前将页面的baseURI设置为与子项目的位置相同,以便在子项的上下文中解析相对URL。

简而言之,可以说:

var originalURI = document.baseURI; // store for setting back after the move
document.baseURI = childDocument.location; // setting parent's baseURI (NO EFFECT!)
childDocument.contentWindow.moveOn();
document.baseURI = originalURI; // restore original baseURI

不幸的是,baseURI属性只读。幸运的是,它的值来自<base>标记,您可以使用脚本进行更改。您可以通过将父级的基本标记设置为引用childUrl来获取给定子级所需的功能:

<head>
<base href="/path/to/child.html" />
</head>

不幸的是,这使得父母相对于孩子的任何相对链接,这不是你想要的。我们需要在点击链接后立即设置,并在将孩子告知moveOn()后将其设置回来。

如果您在父级<base />中添加了空<head>标记,则默认情况下不会影响baseURI。因此,当您想要在子项中执行moveOn()函数时,您可以这样说:

var baseElement = document.getElementsByTagName("base")[0];

// adopt the child's location as baseURI
baseElement.href = childDocument.location; 

childDocument.contentWindow.moveOn();

// revert back to the parent's original baseURI
baseElement.removeAttribute("href"); 

(希望这会有所帮助 - 两年后......哈哈)

修改

互联网爆炸者再一次成为派对的一员。似乎加载后对任何标记的更改都不受尊重。因此,除非您不必支持IE(HA!),否则此解决方案将无效,除非您乐意将子位置硬编码到父级标记中。再一次,这些都很重要。