【问题标题】:.Net Core 2.1 - Read appsettings.json in javascript file.Net Core 2.1 - 在 javascript 文件中读取 appsettings.json
【发布时间】:2018-09-27 07:28:31
【问题描述】:

我在 .net Core 2.1 中有一个使用 signalR 的 Web 应用程序。我需要将 HubUrl 传递到自定义 javascript 文件中。这在 .net Core 中可行吗?

js代码示例:

const connection = new signalR.HubConnectionBuilder()
.withUrl('http://localhost:5000/hub') //Here I need to read appSettings.json to get value from there
.configureLogging(signalR.LogLevel.Information)
.build();

【问题讨论】:

  • 如果您的 javascript 在视图中并且您正在使用某种视图引擎,例如 razor。您可以查看该帖子以获取解决方案stackoverflow.com/questions/48979294/…
  • @maximelian1986 问题是我只是像<script src="~/lib/signalr/signalr.js"></script> <script src="~/js/signalrCustom.js"></script>那样在我的视图中引用这个Js文件

标签: javascript asp.net-core .net-core asp.net-core-mvc signalr


【解决方案1】:

appsettings.json 位于服务器上。因此,您需要将端点添加到返回所需值的控制器。

控制器:

public class MyController:Controller{
    private readonly IConfiguration configuration;

    public MyController(IConfiguration configuration){
         this.configuration = configuration;
    }

    [HTTPGet]
    public ActionResult GetConfigurationValue(string sectionName, string paramName){
        var parameterValue= configuration[$"{sectionName}:{paramName}"];
        return Json(new { parameter= parameterValue});
    }
}

客户端:

$.ajax({
    type:"GET",
    url: "/MyController/GetConfigurationValue"
    data:{
        sectionName = "MySection",
        paramName = "MyParameter"
    }
}).done(
    function(parameterValue){
        //do what you need
});

在 appsettings.json 中:

{
    "MySection":{
        "MyParameter":"value that I want to get"
    }
}

【讨论】:

  • 像魅力一样工作。非常感谢。
  • 请注意,这种实现非常危险,因为它允许任何人读取任何配置值,包括连接字符串或其他内部值之类的秘密。如果您希望有一个端点来返回配置值,您应该将其限制为很少的显式值和/或具有非常强大的输入验证以防止人们访问关键信息。
  • 每次读取设置值时都会触发控制器。尝试将所有配置值拉为列表。确保您的秘密得到管理。
  • @Kurkula,不,这个实现只运行一次。它对控制器进行 AJAX 调用,然后在 AJAX 调用完成时执行一个函数,该函数可能会使用 parameterValue 的值执行某些操作。但是,我确实同意您的观点,控制器将更好地实现以将所有需要的配置值作为列表提取,以便每个页面视图只点击一次控制器。在当前形式下,当您需要多个配置值时,AJAX 调用不可重用,但这不是 OP 问题的一部分。
【解决方案2】:

appsettings.json

"ApiUrls": {
    "commonUrl": "https://localhost:44348/api/"    
  }

_Layout.cshtml

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<script>      
        const commonUrl = @Json.Serialize(@Configuration.GetSection("ApiUrls").GetSection("commonUrl").Value)
</script>

现在这就像一个可供所有 js 文件访问的全局变量

【讨论】:

    【解决方案3】:

    执行此操作的一种非常安全且灵活的方法是在视图中的 &lt;script&gt; 块内公开 URL。这样,您就不会暴露应用程序配置(您必须很好地保护哪些访问),而只是显式地暴露一个安全值。

    它还有一个额外的好处,即您不需要向端点发出请求(您实际上还需要在脚本中知道哪个地址),而是在需要时立即获得价值。

    为此,您可以简单地渲染一个在全局范围内定义值的&lt;script&gt; 标记。例如,您可以在布局中包含以下内容:

    <script>
    window._signalRAddress = @Json.Serialize(ViewData["SignalRAddress"]);
    </script>
    <script src="~/your-custom-script.js"></script>
    

    然后您只需在脚本中使用window._signalRAddress

    【讨论】:

    • 我相信这是一个更好的解决方案。
    • 我在几个 Web 应用程序中使用了这种方法。但是,我最近在使用内容安全策略 (CSP) 有效地将可以由浏览器执行的脚本列入白名单时遇到了麻烦。有了 CSP 脚本策略,我需要添加 'unsafe-inline' 作为例外,有效地允许执行 any 内联脚本,包括可能被恶意注入的内容。 (因此为什么该政策被命名为“不安全”)。如果您开始采用 CSP,请注意一些事情!
    • @BlairAllen 这确实适用于任何类型的内联脚本。或者,您也可以有一个控制器操作,例如返回一个动态呈现的 JavaScript 文件。
    【解决方案4】:

    在带有 webpack 的 SPA 中,您只需导入 appsettings.json 并通过您导入的便利类使其可用;

    例如

    appsettings.js:

    appsettingsjson = process.env.NODE_ENV === 'development'
        ? require('./appsettings.Development.json')
        : require('./appsettings.json');
    
    class AppConfig {
    
        constructor() {
        }
    
        static Settings() {
            return appsettingsjson;
        }
    }
    
    module.exports = AppConfig;
    

    然后在您需要的地方,只需导入和使用。例如:

    const AppConfig = require("./appsettings");
    console.log(AppConfig.Settings().YourSection.YourParameter)
    

    【讨论】:

      【解决方案5】:

      尊重“Maxemelian”的答案,通过添加验证案例来扩展答案

      1. 如果部分名称为空
      2. 忽略秘密
      private readonly IConfiguration configuration;
      
      public MyController(IConfiguration configuration){
           this.configuration = configuration;
      }
      
      [HttpGet("[action]")]
      public ActionResult GetConfigurationValue(string sectionName, string paramName)
      {
          if (paramName.ToLower().Contains("secret")) {
              return null;
          }
      
          var parameterValue = (!string.IsNullOrEmpty(sectionName)) ? config[$"{sectionName}:{paramName}"] : config[$"{paramName}"];
          return Json(new { parameter = parameterValue });
      }
      

      【讨论】:

      • 我建议您的控制器拒绝(返回 null)所有参数名称除了您列入白名单的参数名称。在您当前的实现中,如果您将 secret2 添加到您的配置中但忘记更新此控制器代码,您将意外暴露该新秘密值。
      猜你喜欢
      • 1970-01-01
      • 2020-01-28
      • 1970-01-01
      • 2018-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多