简体   繁体   English

如何在Javascript中获取相对路径?

[英]How to get relative path in Javascript?

In my ASP.net web project, I've written the following Javascript code in a .js file: 在我的ASP.net Web项目中,我在.js文件中编写了以下Javascript代码:

function getDeviceTypes() {
    var deviceTypes;
    $.ajax({
        async: false,
        type: "POST",
        url: "Controls/ModelSelectorWebMethods.aspx/getDeviceTypes",
        data: '{ }',
        contentType: "application/json;",
        dataType: "json",
        success: function(response) {
            deviceTypes = response.d;
        },
        error: function(xhr, status) {
            debugger;
            alert('Error getting device types.');
        }
    });    // end - $.ajax
    return deviceTypes;
}

It was working great until I tried to load this .js file into a page in a subdirectory. 在我尝试将此.js文件加载到子目录中的页面之前,它工作得很好。

Let's suppose that the name of my project is widget . 假设我的项目名称是widget

When I use this code in the main virtual directory, Javascript interprets Controls/ModelSelectorWebMethods.aspx/getDeviceTypes to mean https://mysite.com/widget/Controls/ModelSelectorWebMethods.aspx/getDeviceTypes and all is well. 当我在主虚拟目录中使用此代码时,Javascript将Controls/ModelSelectorWebMethods.aspx/getDeviceTypes解释为https://mysite.com/widget/Controls/ModelSelectorWebMethods.aspx/getDeviceTypes ,一切都很好。 However, from the page in a subdirectory, Javascript interprets it to mean https://mysite.com/widget/subdirectory/Controls/ModelSelectorWebMethods.aspx/getDeviceTypes and it doesn't work. 但是,从子目录中的页面,Javascript将其解释为https://mysite.com/widget/subdirectory/Controls/ModelSelectorWebMethods.aspx/getDeviceTypes ,它不起作用。

How can I write my Javascript code so that the AJAX web method can be called from pages in any directory in my application? 如何编写我的Javascript代码,以便可以从我的应用程序中任何目录中的页面调用AJAX Web方法?

You've got two options: 你有两个选择:

  1. Build a configuration/ preferences object in JavaScript which contains all your environment specific settings: 在JavaScript中构建配置/首选项对象,其中包含所有特定于环境的设置:

      var config = { base: <% /* however the hell you output stuff in ASPX */ %>, someOtherPref: 4 }; 

    and then prefix the AJAX url with config.base (and change the value for config.base whether you're on a dev/ testing/ deployment server.) 然后前缀AJAX的URL与config.base (和更改值config.base无论你是一个开发/测试/部署服务器上。)

  2. Use the <base /> HTML tag to set the URL prefix for all relative URL's. 使用<base /> HTML标记为所有相对URL设置URL前缀。 This affects all relative URL's: image's, links etc. 这会影响所有相对URL:图像,链接等。

Personally, I'd go for option 1. You'll most likely find that config object coming in handy elsewhere. 就个人而言,我会选择选项1.您很可能会发现配置对象在其他地方派上用场。

Obviously the config object will have to be included in a part of your site where server-side-code is evaluated; 显然,配置对象必须包含在您的站点中评估服务器端代码的部分; a .js file won't cut it without configuring your server. 如果不配置服务器, .js文件将不会删除它。 I always include the config object in the HTML <head> ; 我总是在HTML <head>包含配置对象; its a small config object, whose contents can change on each page, so it's perfectly warrented to stick it in there. 它是一个小的配置对象,其内容可以在每个页面上进行更改,因此完全可以将其粘贴在那里。

As long as you don't care about asp.net virtual directories (which makes it actually impossible to figure out from script, you'll have to pass something from the server) you can look at the URL and parse it: 只要你不关心asp.net 虚拟目录 (这实际上不可能从脚本中找出来,你必须从服务器传递一些东西),你可以查看URL并解析它:

function baseUrl() {
   var href = window.location.href.split('/');
   return href[0]+'//'+href[2]+'/';
}

then: 然后:

...
   url: baseUrl()+"Controls/ModelSelectorWebMethods.aspx/getDeviceTypes",
...

... and now I see from your comments above that virtual directories are a problem. ...现在我从上面的评论中看到虚拟目录是个问题。 I usually do this. 我通常这样做。

1) In your masterpage, put code to inject a script somewhere, preferably before anything else (I add it directly to HEAD by adding controls instead of using ScriptManager) to make sure it's run before any other script. 1)在你的母版页中,放置代码以在某处注入脚本,最好在其他任何东西之前(我通过添加控件而不是使用ScriptManager将它直接添加到HEAD)以确保它在任何其他脚本之前运行。 c#: C#:

string basePath = Request.ApplicationPath;
// Annoyingly, Request.ApplicationPath is inconsistent about trailing slash
// (if not root path, then there is no trailing slash) so add one to ensure 
// consistency if needed
string myLocation = "basePath='" + basePath + basePath=="/"?"":"/" + "';";
// now emit myLocation as script however you want, ideally in head

2) Change baseUrl to include that: 2)更改baseUrl以包括:

function baseUrl() {
   var href = window.location.href.split('/');
   return href[0]+'//'+href[2]+basePath;
}

Create an app root variable... 创建应用程序根变量...

var root = location.protocol + "//" + location.host;

And use an absolute URI (instead of relative) when you are making AJAX requests... 在进行AJAX请求时使用绝对URI(而不是相对)...

url: root + "/Controls/ModelSelectorWebMethods.aspx/getDeviceTypes"

I think this function will work... it is to get a relative path as "../../../" so if you invoke this function in each page, this will return a relative path format. 我认为这个函数可以工作......它是一个相对路径为“../../../”所以如果你在每个页面中调用这个函数,这将返回一个相对路径格式。

function getPath() {
    var path = "";
    nodes = window.location. pathname. split('/');
    for (var index = 0; index < nodes.length - 3; index++) {
        path += "../";
    }
    return path;
}

You can import the namespace at the beginning: System.Web.Hosting.HostingEnvironment 您可以在开头导入名称空间:System.Web.Hosting.HostingEnvironment

  <%@ Master Language="VB" AutoEventWireup="false" CodeFile="Site.master.vb" Inherits="Site" %> <%@ Import namespace="System.Web.Hosting.HostingEnvironment" %> 

and on js: 并在js上:

  <script type="text/javascript"> var virtualpathh = "<%=ApplicationVirtualPath %>"; </script> 

Could you use window.location.pathname ? 你能用window.location.pathname吗?

var pathname = window.location.pathname;
$.ajax({
    //...
    url: pathname + 'Controls/...', // might need a leading '/'
    //...
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM