【问题标题】:Get proper root in javascript file在 javascript 文件中获取正确的根目录
【发布时间】:2016-02-20 21:39:48
【问题描述】:

在将 IIS 上的应用程序部署到我们的开发服务器之后,我在解析本地计算机之间的 URL 根目录时遇到问题。

本地运行时的url是这样的。 http://localhost:57173/

在开发服务器上运行时的 url 是这样的。 http://ServerName/AppName

我有对 Web api 的 JQuery Ajax 调用,如果尾部斜杠被省略,它将无法在开发服务器上找到位置。

电话来了

$.ajax({
    type: "GET",
        url: "api/MyApi/Get",
        data: { period: selectedPeriod },
        cache: false,
        success: function (data) {

        }
    });

如果我在开发服务器上的 api 调用中查看 FireBug,并保留尾部斜杠,它将显示

http://ServerName/api/MyApi/Get

如果我确实有斜杠,它会正确解决这个问题。 (注意现在包含 AppName。)

http://ServerName/AppName/api/MyApi/Get

我在这里缺少什么?当我将应用程序移动到此服务器时,它似乎没有找到正确的根目录。尾部斜杠在本地没有区别。无论哪种方式,它都会找到 api。任何想法如何解决这个问题?

【问题讨论】:

    标签: javascript asp.net-mvc iis asp.net-web-api


    【解决方案1】:

    没有前导斜杠的 url 被认为是相对 url。您的 url "api/MyApi/Get" 将由浏览器相对于包含脚本的页面的 url 解析。

    http://ServerName/AppName 在浏览器看来就像是一个页面请求,其中 AppName 是页面的名称,解析 url 时不考虑 AppName。

    http://ServerName/AppName/(斜杠)在浏览器中显示为目录请求,并成为您的相对 url 的基础。

    最好的解决办法可能是将http://ServerName/AppName 的请求重定向到http://ServerName/AppName/

    要在您的应用程序中进行重定向,请将以下内容插入您的 /Home/Index 控制器操作(在任何其他代码之前)

    if (!Request.Url.AbsolutePath.EndsWith("/"))
    {
        return Redirect("~/");
    }
    

    这会将http://ServerName/AppName 的任何请求重定向到http://ServerName/AppName/ 作为副作用,它还会将http://ServerName/AppName/Index 的任何请求重定向到http://ServerName/AppName/,但我认为这不会给您带来任何问题。

    【讨论】:

    • 很好的解释。你能详细说明如何进行重定向吗?我对此仍然很陌生,我一直在研究如何添加缺少的斜杠。默认路由设置为显示主页/索引,因此无论哪种方式它仍会转到该页面。
    【解决方案2】:

    Javascript 通常不会运行,除非用户导致事件发生。我更喜欢使用以下内容,因为它允许 MVC 每次无论您在哪里部署都能正确获取准确的路由。

    HTML

    <button data-url="@Url.Action("MyApi", "Get")"></button>
    

    Javascript

    $(document).ready(function()
    {
      $('button').on('click', function()
      {
        var url = $(this).data('url');
        $.ajax({
          type: "GET",
          url: url,
          data: { period: selectedPeriod },
          cache: false,
          success: function (data) {
        });
      });
    });
    

    我认为在 javascript 中对 url 进行硬编码是不好的做法。

    【讨论】:

    • 好吧,就我而言,我在页面加载时运行了三个 Web api 调用来填充一些表。同样在选择的更改事件上再次运行这些,但我看不到如何传递 url 信息以在页面加载时做好准备,而没有事件启动 Javascript。
    • 那么,为什么表格没有 url 作为数据属性?基本上使您的代码可重用,因为它可以查询表并获取包含表所需数据的 url。
    【解决方案3】:

    我也遇到了这个问题,解决方法是声明一个 javascript 变量,其中包含在两个环境(开发和本地)中不同的 url 部分,并将其添加到每个 ajax 请求:

    我将该变量放在布局文件 (Views/Shared/_Layout.cshtml) 中,以便它可以由 ASP.NET 自动填充,然后全局使用(确保在调用 @RenderSection 之前创建脚本):

      ...
      <script>
        var baseUrl = @Html.Raw(Json.Encode(Url.Content("~")));
      </sctipt>
      @RenderSection("scripts", required: false) 
    </body>
    ...
    

    然后在 ajax 调用的 url 中添加该变量(例如 View/Home/Index.cshtml):

        @section scripts {
          $.ajax({
            type: "GET",
            url: baseUrl + "api/MyApi/Get",
            data: { period: selectedPeriod },
            cache: false,
            success: function (data) {} 
         });
       }
    

    【讨论】:

    • 我喜欢这个。这就是我想做的,但不知道怎么做。我使用 Url.Action 方法修复了同一环境中锚标记中的 href 的另一个问题。我会尝试将其转移到 JavaScript 中。谢谢
    • 我不确定这有什么问题。如果我转到http://ServerName/AppNamehttp://ServerName/AppName/http://ServerName/AppName/Home,baseUrl 变量将为/AppName/ 并且一切正常,但如果我尝试另一个页面,如http://ServerName/AppName/Other,baseUrl 将显示为/AppName/Other。为什么这没有获得相同的基本 URL?
    • 我找到了答案,我将 _Layout 中的脚本更改为 var baseUrl = @Html.Raw(Json.Encode(@Url.Content("~/")));,它现在返回正确的基本 URL。你能解释一下这里的区别吗?如果您觉得这很合适,请更新您的回复,我会将其标记为答案。
    • 让我做一些测试,我会调整答案
    • 作为 @richard [stackoverflow.com/a/8186202/1416077](comments)Url.Action 方法旨在解析一个动作控制器 url,当我们说 Url.Action("") 时,我们正在解析当前控制器中的索引动作: HomeController => /AppName/, OtherController => /AppName/Other 在 HomeController 的情况下我们只得到 /AppName/ 因为是默认控制器(在 /App_Start/RouteConfig.cs 中配置)。 Url.Content("~") 更适合解析任何以“~”通配符获取的web根目录下的url。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-27
    • 2018-06-04
    • 1970-01-01
    • 2013-09-07
    • 2011-02-17
    • 2010-10-03
    • 2017-09-28
    相关资源
    最近更新 更多