首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将服务器端配置数据传递给客户端$rootScope的最佳方法

将服务器端配置数据传递给客户端$rootScope的最佳方法
EN

Stack Overflow用户
提问于 2016-08-22 20:52:57
回答 1查看 1K关注 0票数 0

因此,我有一个基本的web应用程序与服务器端认证。然后,有一个用于UI的前端角度框架,它由指令和角服务工厂驱动。

这个角度的框架需要了解有关当前页面请求的事情。

  • 用户是否经过身份验证?
  • 谁是经过验证的用户?
  • 他们的认证角色是什么?

等。

这是每个请求的通用数据。

我试图找出最好的方式提供服务器端的信息到前端的角度框架。

起初,我想我应该把它放在HTTP头中,但是如果不发出额外的ajax请求,您就不能访问javascript中的HTTP头,然后将整个应用程序从最初的ajax请求的链中提取出来。

在初始页面请求的响应过程中,数据是已知的,所以我想向它提供该响应。

我知道,我可以用一个隐藏的领域在头部标签,但这似乎是相当麻烦,我希望我最好回避这一点。

我唯一能想到的另一件事是使用,并尝试将javascript注入响应以初始化框架上下文。

例如,我可以将手动角度引导代码移动为动态服务器端代码,将其注入响应的末尾(最后运行脚本),并动态生成angular.module(.).run函数,然后以这种方式将全局页面数据注入$rootScope。

编辑:我也可以在初始响应中使用cookie,当脚本运行时它就会出现在那里。

是否有更好的方法来解决这个问题,或者MVC-6中的新特性?

EN

回答 1

Stack Overflow用户

发布于 2016-08-23 03:28:46

除非有人找到更好的方法,否则暂时回答。

我在MVC6om ASP.Net Core1.0中创建了一个,它在执行任何操作之后,但在对该操作进行处理之前运行。我使用它来构建一个匿名对象,它是我想要服务给我的前端JS的所有数据的匿名对象。

代码语言:javascript
运行
复制
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ihq.moth.common.Filters
{
    public class ApiInjectFilter : IActionFilter
    {
        public void OnActionExecuted(ActionExecutedContext context)                
        {
            ///This Code is used to setup json data in a the ViewData Dictionary used by the client side script API, like knowing who the current user is, if they are authenticated, what permissions they have etc (of course the permissions are only used for cosmetic nice haves, permissions are double checked server side).
            var isAuthenticated = context.HttpContext.User != null && context.HttpContext.User.Identity != null && context.HttpContext.User.Identity.IsAuthenticated;
            var initData = new
            {
                isAuthenticated = isAuthenticated
                //TODO Add User Later                
            };

            var json = JsonConvert.SerializeObject(initData);
            var controller = context.Controller as Controller;

            controller.ViewData["APP_API_INIT_JS"] = json;
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {

        }
    }
}

然后您需要在Startup.cs配置服务方法中配置它.

代码语言:javascript
运行
复制
   //Configure Services

   public void ConfigureServices(IServiceCollection services)
   {
        // Add framework services.
        services.AddMvc(options => {
            options.Filters.Add(typeof(common.Filters.ApiInjectFilter), 0);       //My Filter is added here with order 0 (first)
        });  
        .......
   }

对于每个控制器动作请求(驱动我的整个应用程序、传统MVC get等),这个APIFilter将运行并将javascript InitData (基本上是javascript对象(raw,而不是json))添加到ViewEngine的ViewData词典中。这将使它在任何视图的上下文中都可用。

然后,我创建了一个部分视图来动态地为我的应用程序构建基本名称空间,并从视图包加载这个初始化Javascript。

代码语言:javascript
运行
复制
@{
    Layout = null;
    var initJsCode = this.ViewData["APP_API_INIT_JS"]; //this is the javascript generated in the Global Action Filter further above that runs after every action, and will contain Page Request Object data in javascript that every page shares (like authentication data and service end point urls etc.

}
<script>
    var moth = moth || (function () {
        return new function () {
            this.getInitData = function () {
                return @Html.Raw(initJsCode);
            }
        }
    })();
</script>

然后,我修改了我的_Layout.Cshtml文件以使用这个部分视图:注意,部分视图是在两个地方调用的,因为一个环境块用于开发模式,另一个用于生产。

代码语言:javascript
运行
复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Meower Of The Hour</title>
    <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</head>
<body>
    <div id="mainWrapper" class="container-fluid">
        @{ Html.RenderPartial("Navbar");}
        @RenderBody()
    </div>
    <environment names="Development">
        <script src="~/js/jquery.js"></script>
        <script src="~/js/angular.js"></script>
        <script src="~/js/angular-messages.js"></script>
        <script src="~/js/bootstrap.js"></script>        
        @Html.Partial("_InitJSData") //load my namespace with the getInitData method in it
        <script asp-src-include="~/js/app.js"></script>
        <script asp-src-include="~/js/services/*.js"></script>
        <script asp-src-include="~/js/directives/*.js"></script>
        <script asp-src-include="~/js/controllers/*.js"></script>
        <script src="~/js/appLast.js"></script>
    </environment>
    <environment names="Production">
        @Html.Partial("_InitJSData") //load my namespace with the getInitData method in it
        <script src="~/js/scripts.min.js" asp-append-version="true"></script>
    </environment>
</body>
</html>

最后,将其放在rootScope对象上并删除appJsonInitData的全局变量(驻留在app.js中)并在_InitJSData部分视图之后加载的角形JS代码;

代码语言:javascript
运行
复制
(function(){
    var app = angular.module('moth', [])
    .run(['$rootScope', function ($rootScope) {
        $rootScope.appData = moth.getInitData(); //moth.getInitData is from the partial view above that was made dynamically and will be different for every request.
    }]);
})();

最后的想法

这是我想出的最好的方法,它不使用cookie,也不需要页面加载后的ajax请求来获得它。请记住,当我完成任务时,会有更多的数据从getInitData返回。它将包含所有API中使用的、特定于每个请求的基于上下文的信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39088559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档