使用 JavaScript 将相对路径转换为绝对路径
Convert relative path to absolute using JavaScript
有一个函数,它给了我这样的网址:
./some.css
./extra/some.css
../../lib/slider/slider.css
它始终是一条相对路径。
假设我们知道页面的当前路径,例如http://site.com/stats/2012/
,不确定如何将这些相对路径转换为真实路径?
我们应该得到这样的东西:
./some.css => http://site.com/stats/2012/some.css
./extra/some.css => http://site.com/stats/2012/extra/some.css
../../lib/slider/slider.css => http://site.com/lib/slider/slider.css
没有jQuery,只有vanilla javascript。
最简单、最有效和最正确的方法是只使用 URL api。
new URL("http://www.stackoverflow.com?q=hello").href;
//=> "http://www.stackoverflow.com/?q=hello"
new URL("mypath","http://www.stackoverflow.com").href;
//=> "http://www.stackoverflow.com/mypath"
new URL("../mypath","http://www.stackoverflow.com/search").href
//=> "http://www.stackoverflow.com/mypath"
new URL("../mypath", document.baseURI).href
//=> "https://stackoverflow.com/questions/mypath"
在性能方面,此解决方案与使用字符串操作相当,并且比创建a
标签快两倍。
Javascript会为你做。无需创建函数。
var link = document.createElement("a");
link.href = "../../lib/slider/slider.css";
alert(link.protocol+"//"+link.host+link.pathname+link.search+link.hash);
// Output will be "http://www.yoursite.com/lib/slider/slider.css"
但是,如果您需要将其作为函数:
var absolutePath = function(href) {
var link = document.createElement("a");
link.href = href;
return (link.protocol+"//"+link.host+link.pathname+link.search+link.hash);
}
更新:如果您需要完整的绝对路径,则更简单的版本:
var absolutePath = function(href) {
var link = document.createElement("a");
link.href = href;
return link.href;
}
这应该可以做到:
function absolute(base, relative) {
var stack = base.split("/"),
parts = relative.split("/");
stack.pop(); // remove current file name (or empty string)
// (omit if "base" is the current folder without trailing slash)
for (var i=0; i<parts.length; i++) {
if (parts[i] == ".")
continue;
if (parts[i] == "..")
stack.pop();
else
stack.push(parts[i]);
}
return stack.join("/");
}
这是来自 MDN 的牢不可破!
/*'
|*|
|*| :: translate relative paths to absolute paths ::
|*|
|*| https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
|*|
|*| The following code is released under the GNU Public License, version 3 or later.
|*| http://www.gnu.org/licenses/gpl-3.0-standalone.html
|*|
'*/
function relPathToAbs (sRelPath) {
var nUpLn, sDir = "", sPath = location.pathname.replace(/[^'/]*$/, sRelPath.replace(/('/|^)(?:'.?'/+)+/g, "$1"));
for (var nEnd, nStart = 0; nEnd = sPath.indexOf("/../", nStart), nEnd > -1; nStart = nEnd + nUpLn) {
nUpLn = /^'/(?:'.'.'/)*/.exec(sPath.slice(nEnd))[0].length;
sDir = (sDir + sPath.substring(nStart, nEnd)).replace(new RegExp("(?:'''/+[^'''/]*){0," + ((nUpLn - 1) / 3) + "}$"), "/");
}
return sDir + sPath.substr(nStart);
}
示例用法:
/* Let us be in /en-US/docs/Web/API/document.cookie */
alert(location.pathname);
// displays: /en-US/docs/Web/API/document.cookie
alert(relPathToAbs("./"));
// displays: /en-US/docs/Web/API/
alert(relPathToAbs("../Guide/API/DOM/Storage"));
// displays: /en-US/docs/Web/Guide/API/DOM/Storage
alert(relPathToAbs("../../Firefox"));
// displays: /en-US/docs/Firefox
alert(relPathToAbs("../Guide/././API/../../../Firefox"));
// displays: /en-US/docs/Firefox
如果要对浏览器中自定义网页中的链接进行相对到绝对的转换(而不是运行脚本的页面(,则可以使用 @Bergi 建议的函数的更增强版本:
var resolveURL=function resolve(url, base){
if('string'!==typeof url || !url){
return null; // wrong or empty url
}
else if(url.match(/^[a-z]+':'/'//i)){
return url; // url is absolute already
}
else if(url.match(/^'/'//)){
return 'http:'+url; // url is absolute already
}
else if(url.match(/^[a-z]+':/i)){
return url; // data URI, mailto:, tel:, etc.
}
else if('string'!==typeof base){
var a=document.createElement('a');
a.href=url; // try to resolve url without base
if(!a.pathname){
return null; // url not valid
}
return 'http://'+url;
}
else{
base=resolve(base); // check base
if(base===null){
return null; // wrong base
}
}
var a=document.createElement('a');
a.href=base;
if(url[0]==='/'){
base=[]; // rooted path
}
else{
base=a.pathname.split('/'); // relative path
base.pop();
}
url=url.split('/');
for(var i=0; i<url.length; ++i){
if(url[i]==='.'){ // current directory
continue;
}
if(url[i]==='..'){ // parent directory
if('undefined'===typeof base.pop() || base.length===0){
return null; // wrong url accessing non-existing parent directories
}
}
else{ // child directory
base.push(url[i]);
}
}
return a.protocol+'//'+a.hostname+base.join('/');
}
如果出现问题,它会返回null
。
用法:
resolveURL('./some.css', 'http://example.com/stats/2012/');
// returns http://example.com/stats/2012/some.css
resolveURL('extra/some.css', 'http://example.com/stats/2012/');
// returns http://example.com/stats/2012/extra/some.css
resolveURL('../../lib/slider/slider.css', 'http://example.com/stats/2012/');
// returns http://example.com/lib/slider/slider.css
resolveURL('/rootFolder/some.css', 'https://example.com/stats/2012/');
// returns https://example.com/rootFolder/some.css
resolveURL('localhost');
// returns http://localhost
resolveURL('../non_existing_file', 'example.com')
// returns null
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;
}
这也适用于IE6,不像其他一些解决方案(请参阅从相对URL获取绝对URL。(IE6 问题((
建议和接受的解决方案不支持服务器相对 URL,并且不适用于绝对 URL。例如,如果我的亲戚是/sites/folder1,它将无法工作。
这是另一个支持完整,服务器相对或相对URL以及.的函数。/为一级以上。它并不完美,但涵盖了很多选择。当您的基本网址不是当前页面网址时,请使用此选项,否则有更好的替代方法。
function relativeToAbsolute(base, relative) {
//make sure base ends with /
if (base[base.length - 1] != '/')
base += '/';
//base: https://server/relative/subfolder/
//url: https://server
let url = base.substr(0, base.indexOf('/', base.indexOf('//') + 2));
//baseServerRelative: /relative/subfolder/
let baseServerRelative = base.substr(base.indexOf('/', base.indexOf('//') + 2));
if (relative.indexOf('/') === 0)//relative is server relative
url += relative;
else if (relative.indexOf("://") > 0)//relative is a full url, ignore base.
url = relative;
else {
while (relative.indexOf('../') === 0) {
//remove ../ from relative
relative = relative.substring(3);
//remove one part from baseServerRelative. /relative/subfolder/ -> /relative/
if (baseServerRelative !== '/') {
let lastPartIndex = baseServerRelative.lastIndexOf('/', baseServerRelative.length - 2);
baseServerRelative = baseServerRelative.substring(0, lastPartIndex + 1);
}
}
url += baseServerRelative + relative;//relative is a relative to base.
}
return url;
}
希望这有帮助。在 JavaScript 中没有这个基本实用程序真的很令人沮丧。
这是一个非常古老的问题,但你可以用: (new URL(relativePath, location)).href
.
href 解决方案仅在加载文档后有效(至少在 IE11 中(。 这对我有用:
link = link || document.createElement("a");
link.href = document.baseURI + "/../" + href;
return link.href;
见 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
我必须为接受的解决方案添加修复程序,因为我们可以在 angularjs 导航中的 # 后有斜杠。
function getAbsoluteUrl(base, relative) {
// remove everything after #
var hashPosition = base.indexOf('#');
if (hashPosition > 0){
base = base.slice(0, hashPosition);
}
// the rest of the function is taken from http://stackoverflow.com/a/14780463
// http://stackoverflow.com/a/25833886 - this doesn't work in cordova
// http://stackoverflow.com/a/14781678 - this doesn't work in cordova
var stack = base.split("/"),
parts = relative.split("/");
stack.pop(); // remove current file name (or empty string)
// (omit if "base" is the current folder without trailing slash)
for (var i=0; i<parts.length; i++) {
if (parts[i] == ".")
continue;
if (parts[i] == "..")
stack.pop();
else
stack.push(parts[i]);
}
return stack.join("/");
}
这将起作用。 但仅当您打开带有其文件名的页面时。 当您打开这样的链接时,它将无法正常工作 stackoverflow.com/page
. 它将适用于stackoverflow.com/page/index.php
function reltoabs(link){
let absLink = location.href.split("/");
let relLink = link;
let slashesNum = link.match(/[.]{2}'//g) ? link.match(/[.]{2}'//g).length : 0;
for(let i = 0; i < slashesNum + 1; i++){
relLink = relLink.replace("../", "");
absLink.pop();
}
absLink = absLink.join("/");
absLink += "/" + relLink;
return absLink;
}
我找到了一个非常简单的解决方案来做到这一点,同时仍然通过使用历史API(IE 10或更高版本(仍然支持IE 10(IE不支持URL-API(。此解决方案无需任何字符串操作即可工作。
function resolveUrl(relativePath) {
var originalUrl = document.location.href;
history.replaceState(history.state, '', relativePath);
var resolvedUrl = document.location.href;
history.replaceState(history.state, '', originalUrl);
return resolvedUrl;
}
history.replaceState()
不会触发浏览器导航,但仍会修改document.location
并支持相对路径和绝对路径。
此解决方案的一个缺点是,如果您已经在使用历史记录 API 并使用标题设置了自定义状态,则当前状态的标题将丢失。
尝试:
/**
* Convert relative paths to absolute paths
* @author HaNdTriX
* @param {string} html - HTML string
* @param {string} baseUrl - base url to prepend to relative paths
* @param {string[]} [attributes] - attributes to convert
* @returns {string}
*/
function absolutify(
html,
baseUrl,
attributes = [
"href",
"src",
"srcset",
"cite",
"background",
"action",
"formaction",
"icon",
"manifest",
"code",
"codebase",
]
) {
// Build the regex to match the attributes.
const regExp = new RegExp(
`(?<attribute>${attributes.join(
"|"
)})=(?<quote>['"])(?<path>.*?)''k<quote>`,
"gi"
);
return html.replaceAll(regExp, (...args) => {
// Get the matched groupes
const { attribute, quote, path } = args[args.length - 1];
// srcset may have multiple paths `<url> <descriptor>, <url> <descriptor>`
if (attribute.toLowerCase() === "srcset") {
const srcSetParts = path.split(",").map((dirtyPart) => {
const part = dirtyPart.trim();
const [path, size] = part.split(" ");
return `${new URL(path.trim(), baseUrl).toString()} ${size || ""}`;
});
return `${attribute}=${quote}${srcSetParts.join(", ")}${quote}`;
}
const absoluteURL = new URL(path, baseUrl).href;
return `${attribute}=${quote}${absoluteURL}${quote}`;
});
}
console.log(
absolutify("<img src='./fooo.png'>", "https://example.com")
)
- 如何使用jquery将base64图像路径转换为真实路径
- 如何将本地文件路径转换为文件::?/url在node.js中的安全性
- Mongoose转换为ObjectId失败,因为值为“”;xxx”;在路径“_id”;
- windows文件路径转换为mac
- D3 svg路径转换摇摆不定(包括jsfiddle)
- 如何将 easejs 路径转换为 svg
- 如何在 Three.js 中将 2D 路径转换为 3D 形状
- 将 Google 地图多边形路径转换为 SVG 路径
- 使用 javascript 将描边路径转换为形状
- 将SVG路径转换为绝对命令
- 在Windows上将相对路径转换为绝对路径
- 将绝对路径转换为相对路径
- 将svg路径转换为多边形,以便在Javascript Clipper中使用
- 将绝对路径转换为相对路径时出错
- NodeJS-将相对路径转换为绝对路径
- 使用 JavaScript 将相对路径转换为绝对路径
- 将路径转换添加到饼图
- 如何在javascript中将所有“链接rel样式表”相对路径转换为绝对路径
- 将目录路径转换为javascript对象
- 将SVG路径转换为相对命令