상대 URL에서 절대 URL 가져 오기. (IE6 문제)
현재 상대 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에서 (서버 요청없이) IE6에서 정규화 된 URL을 얻을 수있는 방법이 있습니까?
빠른 정규식 / 문자열 수정을 권장하기 전에 그렇게 간단하지 않다고 확신합니다. 기본 요소 + 이중 기간 상대 URL + 수많은 다른 잠재적 변수가 정말 지옥을 만듭니다!
거대한 정규식 솔루션을 만들지 않고도 할 수있는 방법이 있어야합니다.
얼마나 이상해! 그러나 IE는 DOM 메서드 대신 innerHTML을 사용할 때이를 이해합니다.
function escapeHTML(s) {
return s.split('&').join('&').split('<').join('<').split('"').join('"');
}
function qualifyURL(url) {
var el= document.createElement('div');
el.innerHTML= '<a href="'+escapeHTML(url)+'">x</a>';
return el.firstChild.href;
}
조금 못 생겼지 만 스스로하는 것보다 더 간결합니다.
브라우저가 <base> 태그를 올바르게 구현하는 한 브라우저는 다음을 수행합니다.
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은 다음과 같습니다. http://jsfiddle.net/ecmanaut/RHdnZ/
요소를 복제하기 만하면 IE6에서 작동하도록 만들 수 있습니다.
function qualifyURL(url) {
var a = document.createElement('a');
a.href = url;
return a.cloneNode(false).href;
}
(IE6 및 IE5.5 모드에서 IETester를 사용하여 테스트 됨)
이 블로그 에서 찾았습니다 @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;
}
나는 그것이 큰 문제가 아니라 조금 더 우아하다는 것을 알았습니다.
URI.js 가 문제를 해결하는 것 같습니다.
URI("../foobar.html").absoluteTo("http://example.org/hello/world.html").toString()
또한보십시오 http://medialize.github.io/URI.js/docs.html#absoluteto
IE6에서는 테스트되지 않았지만 일반적인 문제를 검색하는 다른 사용자에게 도움이 될 수 있습니다.
나는 실제로 원본 문서를 수정할 필요가 없었지만 (일시적으로도 아님) 브라우저의 내장 URL 구문 분석 등을 사용하는 접근 방식을 원했습니다. 또한 내 자신의 기반을 제공 할 수 있기를 원했습니다 (예 : ecmanaught의 답변). 다소 간단하지만 createHTMLDocument를 사용합니다 (조금 더 호환되도록 createDocument로 대체 될 수 있음).
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;
}
이 솔루션은 모든 브라우저에서 작동합니다.
/**
* 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
그러나 "../file.png"와 같이 ".."가 포함 된 상대 URL은 지원하지 않습니다.
이것은 기본 상대 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(/^\.\//, '');
}
jsfiddle에서 테스트하십시오 : https://jsfiddle.net/n11rg255/
브라우저와 node.js 또는 기타 환경에서 모두 작동합니다.
I found this blog post that suggests using an image element instead of an anchor:
http://james.padolsey.com/javascript/getting-a-fully-qualified-url/
That works to reliably expand a URL, even in IE6. But the problem is that the browsers that I have tested will immediately download the resource upon setting the image src attribute - even if you set the src to null on the next line.
I am going to give bobince's solution a go instead.
If url
does not begin with '/'
Take the current page's url, chop off everything past the last '/'; then append the relative url.
Else if url
begins with '/'
Take the current page's url and chop off everything to the right of the single '/'; then append the url.
Else if url
starts with # or ?
Take the current page's url and simply append url
Hope it works for you
If it runs in the browser, this sort of works for me..
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;
}
참고URL : https://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
'programing tip' 카테고리의 다른 글
Double.TryParse 또는 Convert.ToDouble-어느 것이 더 빠르고 안전합니까? (0) | 2020.10.09 |
---|---|
Powershell의 'more'또는 'less'명령과 동일합니까? (0) | 2020.10.09 |
오류가 발생하면 using 문이 데이터베이스 트랜잭션을 롤백합니까? (0) | 2020.10.08 |
codeigniter 웹 사이트를 다국어로 만드는 가장 좋은 방법입니다. (0) | 2020.10.08 |
csvwriter.writerow ()가 각 문자 뒤에 쉼표를 넣는 이유는 무엇입니까? (0) | 2020.10.08 |