JavaScript文件的相对URL

18
我有一些 JavaScript 代码需要向服务器发送查询请求。问题是,我如何找到当前脚本的 URL,以便可以构建用于 AJAX 的正确请求 URL。
也就是说,同一个脚本同时包含在 //help/whatever 等网页中,但请求始终需要来自于 /data.json。此外,相同的站点在不同的服务器上运行,其中 / 文件夹可能被放置在不同的位置。我可以解决相对 URL 的问题(在 ez-publish 模板中),但无法在 JavaScript 文件内部解决这个问题。
是否有适用于所有浏览器的小型脚本可用于此?
5个回答

23

我喜欢将<link>元素放在页面的<head>中,包含用于请求的URL。它们可以由你的服务器端语言生成,因此始终指向正确的视图:

<link id="link-action-1" href="${reverse_url ('action_1')}"/>

变成

<link id="link-action-1" href="/my/web/root/action-1/"/>

可以通过JavaScript检索:

document.getElementById ('link-action-1').href;

这是链接标签的一个很好的应用。 - Jonathan Arkell
我曾想着通过遍历所有脚本标签并找到自己的脚本,然后与之相关联来解决问题。不过这种方法要简单得多。 - Staale
如果你_真的_想要jQuery版本,$("#link-action-1")[0].href - Donal Fellows

3
document.location.href会给你当前的URL,你可以使用JavaScript的字符串函数来操作它。

这对我没有用,因为我需要找到Web应用程序的根目录,这可能因服务器而异(在这种情况下是开发人员的机器设置)。 - Staale
这个Web应用程序使用哪种服务器端技术? - John Topley
Apache,PHP和eZ-publish。但我想要一些纯JavaScript的东西,不受服务器端技术的限制。 - Staale

3

客户端无法确定Web应用程序的根目录,因为它没有服务器配置的知识。一种尝试的选项是使用head元素内的base元素,使服务器动态生成而不是硬编码(以显示每个服务器的相关URL):

<base href="http://path/to/webapp/root/" />

此时所有的URL都将被视为相对于此URL。因此,您只需向/data.json发出请求即可。但是,您需要确保应用程序中的所有其他链接都要考虑到这一点。


看起来这个元素恰好可以解决这个问题。MDN说它也得到了很好的支持:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base - Phil
仔细研究一下 <base>,似乎有些需要注意的重大警告。例如,像 <a href="#top-of-page"> 的锚点链接将会失效。详情请参见:https://dev59.com/enI-5IYBdhLWcg3wYXL8#1889898 - Phil

2
如果脚本知道自己的文件名,您可以使用document.getElementsByTagName()。遍历列表,直到找到与您的匹配的脚本,并以这种方式提取完整(或相对)url。
以下是一个示例:
function getScriptUrl ( name ) {
    var scripts = document.getElementsByTagName('script');
    var re = RegExp("(\/|^)" + name + "$");
    var src;
    for( var i = 0; i < scripts.length; i++){
        src = scripts[i].getAttribute('src');
        if( src.match(re) )
            return src;
    }
    return null;
}

console.log( 'found ' + getScriptUrl('demo.js') );

请考虑到这种方法可能会遇到文件名冲突的问题。


很酷。但是,这在没有src属性的脚本上会出错。如果你将条件调整为if( src && src.match(re)),它就可以工作了。感谢您提供的代码! - Shane Daniel
不错的解决方案。这个方案可靠性如何?在各种浏览器上兼容性如何? - dkamins

0
我在我的库的主入口点(main.php)中包含了以下代码:
/**
 * Build current url, depending on protocal (http/https),
 * port, server name and path suffix
 */
$site_root = 'http';
if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") 
    $site_root .= "s";
$site_root .= "://" . $_SERVER["SERVER_NAME"];
if ($_SERVER["SERVER_PORT"] != "80")
    $site_root .= ":" . $_SERVER["SERVER_PORT"];
$site_root .= $g_config["paths"]["site_suffix"];

$g_config["paths"]["site_root"] = $site_root;

$g_config是一个包含配置选项的全局数组。因此,site_suffix可能看起来像这样:在您的开发框中为“/sites_working/thesite/public_html”,而在具有虚拟主机(域名)的服务器上仅为“/”。

这种方法也很好,因为如果有人键入您的开发框的IP地址,它将使用相同的IP地址来构建路径到javascript文件夹,而不是像“localhost”一样,如果您使用“localhost”,它将使用“localhost”来构建URL。

而且,由于它还检测SSL,如果您将SSL支持添加到服务器,则无需担心资源是否会通过HTTP或HTTPS发送。

然后,在您的模板中,可以使用

<link id="site_root" href="<?php echo $g_config["paths"]["site_root"] ?>"/>

或者

<script type = "text/javascript">
var SiteRoot = "<?php echo $g_config["paths"]["site_root"]; ?>";
</script>

我想后者会更快。


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