Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从相对URL获取绝对URL。(IE6问题)_Javascript_Url_Internet Explorer 6 - Fatal编程技术网

Javascript 从相对URL获取绝对URL。(IE6问题)

Javascript 从相对URL获取绝对URL。(IE6问题),javascript,url,internet-explorer-6,Javascript,Url,Internet Explorer 6,我目前正在使用以下函数将相对URL“转换”为绝对URL: function qualifyURL(url) { var a = document.createElement('a'); a.href = url; return a.href; } 这在大多数浏览器中都很有效,但IE6仍然坚持返回相对URL!如果我使用getAttribute('href'),情况也是如此 我能够从IE6中获得合格URL的唯一方法是创建一个img元素并查询它的“src”属性——问题是它生成

我目前正在使用以下函数将相对URL“转换”为绝对URL:

function qualifyURL(url) {
    var a = document.createElement('a');
    a.href = url;
    return a.href;
}
这在大多数浏览器中都很有效,但IE6仍然坚持返回相对URL!如果我使用getAttribute('href'),情况也是如此

我能够从IE6中获得合格URL的唯一方法是创建一个img元素并查询它的“src”属性——问题是它生成一个服务器请求;我想避免的事情

所以我的问题是:在IE6中,有没有办法从一个相对的URL(没有服务器请求)获得一个完全限定的URL


在推荐快速正则表达式/字符串修复之前,我向您保证,它并没有那么简单。基本元素+双周期相对URL+一吨其他潜在变量真的让它成为地狱

如果
url
不是以“/”开头,那么一定有一种方法可以做到这一点,而不必创建一个庞大的正则表达式解决方案

获取当前页面的url,删除最后一个“/”之后的所有内容;然后附加相对url

否则如果
url
以“/”开头

取下当前页面的url,并切掉单个“/”右侧的所有内容;然后附加url

否则如果
url
以#或开头

获取当前页面的url并简单地附加
url



希望它对你有用

真奇怪!然而,当您使用innerHTML而不是DOM方法时,IE确实理解它

function escapeHTML(s) {
    return s.split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
}
function qualifyURL(url) {
    var el= document.createElement('div');
    el.innerHTML= '<a href="'+escapeHTML(url)+'">x</a>';
    return el.firstChild.href;
}
函数转义EHTML{

返回s.split(“&”).join(“&;”).split(“我发现这篇博客文章建议使用图像元素而不是锚点:

这可以可靠地扩展URL,即使在IE6中也是如此。但问题是,我测试过的浏览器在设置image src属性时会立即下载资源,即使您在下一行将src设置为null


我将尝试bobince的解决方案。

只要浏览器正确实现标记,哪些浏览器倾向于:

function resolve(url, base_url) {
  var doc      = document
    , old_base = doc.getElementsByTagName('base')[0]
    , old_href = old_base && old_base.href
    , doc_head = doc.head || doc.getElementsByTagName('head')[0]
    , our_base = old_base || doc_head.appendChild(doc.createElement('base'))
    , resolver = doc.createElement('a')
    , resolved_url
    ;
  our_base.href = base_url || '';
  resolver.href = url;
  resolved_url  = resolver.href; // browser magic at work here

  if (old_base) old_base.href = old_href;
  else doc_head.removeChild(our_base);
  return resolved_url;
}

这里有一个jsfiddle,您可以在其中试用它:

如果它在浏览器中运行,这种方法对我很有效

  function resolveURL(url, base){
    if(/^https?:/.test(url))return url; // url is absolute
    // let's try a simple hack..
    var basea=document.createElement('a'), urla=document.createElement('a');
    basea.href=base, urla.href=url;
    urla.protocol=basea.protocol;// "inherit" the base's protocol and hostname
    if(!/^\/\//.test(url))urla.hostname=basea.hostname; //..hostname only if url is not protocol-relative  though
    if( /^\//.test(url) )return urla.href; // url starts with /, we're done
    var urlparts=url.split(/\//); // create arrays for the url and base directory paths
    var baseparts=basea.pathname.split(/\//); 
    if( ! /\/$/.test(base) )baseparts.pop(); // if base has a file name after last /, pop it off
    while( urlparts[0]=='..' ){baseparts.pop();urlparts.shift();} // remove .. parts from url and corresponding directory levels from base
    urla.pathname=baseparts.join('/')+'/'+urlparts.join('/');
    return urla.href;
  }

此解决方案适用于所有浏览器

/**
 * Given a filename for a static resource, returns the resource's absolute
 * URL. Supports file paths with or without origin/protocol.
 */
function toAbsoluteURL (url) {
  // Handle absolute URLs (with protocol-relative prefix)
  // Example: //domain.com/file.png
  if (url.search(/^\/\//) != -1) {
    return window.location.protocol + url
  }

  // Handle absolute URLs (with explicit origin)
  // Example: http://domain.com/file.png
  if (url.search(/:\/\//) != -1) {
    return url
  }

  // Handle absolute URLs (without explicit origin)
  // Example: /file.png
  if (url.search(/^\//) != -1) {
    return window.location.origin + url
  }

  // Handle relative URLs
  // Example: file.png
  var base = window.location.href.match(/(.*\/)/)[0]
  return base + url
但是,它不支持带有“.”的相对URL,比如“./file.png”。

似乎解决了这个问题:

URI("../foobar.html").absoluteTo("http://example.org/hello/world.html").toString()
另见

没有使用IE6进行测试,但可能有助于其他人搜索一般问题。

我在这方面发现了另一种看起来像@bobince解决方案的方法

function canonicalize(url) {
    var div = document.createElement('div');
    div.innerHTML = "<a></a>";
    div.firstChild.href = url; // Ensures that the href is properly escaped
    div.innerHTML = div.innerHTML; // Run the current innerHTML back through the parser
    return div.firstChild.href;
}
函数规范化(url){
var div=document.createElement('div');
div.innerHTML=“”;
div.firstChild.href=url;//确保正确转义href
div.innerHTML=div.innerHTML;//通过解析器运行当前innerHTML
返回div.firstChild.href;
}

我发现它更优雅一点,没什么大不了的。

只要克隆元素,就可以在IE6上工作:

function qualifyURL(url) {
    var a = document.createElement('a');
    a.href = url;
    return a.cloneNode(false).href;
}

(在IE6和IE5.5模式下使用IETester进行测试)

这是我用来解析基本相对URL的函数:

function resolveRelative(path, base) {
    // Absolute URL
    if (path.match(/^[a-z]*:\/\//)) {
      return path;
    }
    // Protocol relative URL
    if (path.indexOf("//") === 0) {
      return base.replace(/\/\/.*/, path)
    }
    // Upper directory
    if (path.indexOf("../") === 0) {
        return resolveRelative(path.slice(3), base.replace(/\/[^\/]*$/, ''));
    }
    // Relative to the root
    if (path.indexOf('/') === 0) {
        var match = base.match(/(\w*:\/\/)?[^\/]*\//) || [base];
        return match[0] + path.slice(1);
    }
    //relative to the current directory
    return base.replace(/\/[^\/]*$/, "") + '/' + path.replace(/^\.\//, '');
}
在JSFIDLE上测试它:


它可以在浏览器和node.js或其他环境中工作。

我实际上想要一种不需要修改原始文档(甚至不是暂时的)但仍然使用浏览器内置url解析等的方法。此外,我希望能够提供自己的基础(如ecmanaught的答案)。它相当简单,但使用createHTMLDocument(可以替换为createDocument,以便更兼容):


您忘记了URL可以以“/”开头,这使它们与scheme相对。//foo.com/bar/您还忘记了虚线相对.././语法(此省略是否重要取决于需要输出的内容)你可以用它将相对URI解析为绝对URI。谢谢你,Gumbo,我想这是必须的。我本来希望有一个更简洁的解决方案,但无论如何,谢谢你,我从来都不知道这个js URI类存在!可爱的黑客!不在乎IE6。节省了我的时间。你太棒了。我没有用它工作,我只有“foo”和我想要“”js uri库似乎不符合原始海报的要求。派对已经晚了三年,因此需要一段时间才能登上榜首,而没有市场营销或许多人有这个问题,并且想要一个代码保守且准确的解决方案。除了支持任意基URL之外,这与解决方案有什么不同问题中提到的自动分号?它在IE 6上工作吗?@AmadeusDrZaius不应该,但如果你愿意,它们可以。Javascript只在行尾添加自动分号,这样做不会使下一行成为无效语句。“,foo=1”是一个语法错误,因此整个var语句都是批量计算的,没有分号插入。@AndreasDietrich这是因为您没有将任何参数传递给
base\u url
参数,因此它变为
undefined
,并字符串化为
“undefined”
。您应该传递空字符串。或者,如果要使第二个参数成为可选参数,请使用
our_base.href=base_url|
而不是
我们的_base.href=base\U url
。好主意,@Oriol–没有理由不为不同时传递这两个参数的人提供更友好的默认行为。集成。我在博客上发现了类似的解决方案,它不需要代码来转义:这种方法将null(U+0000)替换为� (U+FFFD),根据。在事物的节点端(用于爬行等),这里的正确库可以通过
npm install URIjs
获得,而不是其他类似名称的库。名为的npm包已更改为
URIjs
不确定我是否遗漏了什么,但IE6(或7、8)不支持
document.implementation.createHTMLDocument
我在使用web应用程序加载和刮取其他页面时使用了它。在jQuery.load的回调中,
$(“#loadedHere”).createElement(“a”).url=“foo”
结果
function absolutize(base, url) {
    d = document.implementation.createHTMLDocument();
    b = d.createElement('base');
    d.head.appendChild(b);
    a = d.createElement('a');
    d.body.appendChild(a);
    b.href = base;
    a.href = url;
    return a.href;
}